gpt4 book ai didi

Haskell fromIntegral——类型混淆

转载 作者:行者123 更新时间:2023-12-01 07:09:55 24 4
gpt4 key购买 nike

我正在经历“Real World Haskell”,并且正在做随之而来的练习。

我注意到一些我认为很奇怪的事情。

以这个函数为例:
myAverage :: (Fractional a) => [a] -> Maybe a
myAverage [] = Nothing
myAverage xs = Just $ (mySum xs) / (fromIntegral $ myLength xs)
(/)函数需要两个作为 Fractional 实例的参数.myLength返回 Int所以我用the fromIntegral正如我被告知的那样。

但是fromIntegral仅保证返回值将是 Num 的实例.

为什么Num还“包括”Fractional 的一个实例在这种情况下。不是Fractional更详细?

为什么编译器不提示我只有一个 Num来自返回类型而不是“正确的”Fractional .

为什么我不能使用 Int直接,也是Num的一个实例,不是吗?

在调用mySum的情况下我得到它。它需要一个列表 Num s 但我给它提供了 Fractional 的列表s(也是 Num s,因为它们是从它派生的)。返回类型具有相同的类型,从类型注释中可以看出(见下文):Fractional 的单个元素

但如果是 fromIntegral我无法推断自己(编译器显然可以:-))返回值也是 Fractional 的一个实例.为什么?
它采用的类型显然是 no Fractional .

整个功能按预期工作。

只是为了澄清:
mySum :: (Num a) => [a] -> a
myLength :: [a] -> Int

谢谢,

拉撒路

最佳答案

fromIntegral不会产生一些我们只知道它是 Num 的实例的未知类型. fromIntegral产生我们(通常是隐含地)要求它的任何类型,只要它是 Num 的实例.

就 OO 语言而言,您需要将其视为泛型/模板,而不是虚拟继承/子类型多态。这是 fromIntegral 的等效 Java 签名。看起来像 <A extends Integral, B extends Num> B fromIntegral(A i) ,而不是 Num fromIntegral(Integral i) .

所以如果我们想要一个 Int ,我们得到一个 Int .如果我们想要 Integer ,我们得到一个 Integer .如果我们想要一个 Double , 我们得到一个 Double .但是如果我们想要一个 String ,我们运气不好,因为 String不是 Num 的实例.

在这种情况下,我们需要一个 a在哪里 a是给定列表的元素类型。因此,如果我们传入 Double 的列表年代,fromIntegral给我们一个Double如果我们传入 Rational 的列表年代,fromIntegral给我们一个Rational .

关于Haskell fromIntegral——类型混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31855909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com