5

在玩 Haskell 时遇到了这个问题,我很困惑:

Hugs> :type (\x -> x^2)
\x -> x ^ 2 :: (Integral a, Num b) => b -> b

里面在做什么a?我该怎么读?如果我在 GHCi 中输入相同的内容,它会给出我期望的输出:

Prelude> :type (\x -> x^2)
(\x -> x^2) :: Num a => a -> a

这是拥抱中的错误吗?

4

2 回答 2

7

Integral约束来自 的指数2。请记住,在 Haskell 中,整数文字实际上是 type 的多态值Num a => a。然后编译器推断,由于它被用作 的指数(^) :: (Num a, Integral b) => a -> b -> a,它必须是更受约束的类型Integral a => a

为了让您不必在整个代码中消除数字文字的歧义,Haskell 使用类型默认来为任何不受约束的数字类型选择合理的具体类型。在这种情况下,那将是Integer. 不同之处似乎在于:typeHugs 报告了在此发生之前推断的类型,而 GHCi 报告了应用类型默认值之后的类型。

如果您自己为指数指定具体类型,额外的约束就会消失。

Hugs> :type (\x -> x^(2 :: Integer))
\x -> x ^ 2 :: Num a => a -> a
于 2011-11-03T17:19:59.447 回答
3

这是一种推测,但这可能与(^). :t (^)在 ghci 返回(^) :: (Num a, Integral b) => a -> b -> a。我猜 hugs 认为的第二个参数^需要是一个Integral,即使那个参数只是一个常量 2,它也包含类型签名中的约束。

于 2011-11-03T16:49:31.660 回答