拥抱类型签名包含额外的类型约束?

时间:2011-11-03 16:15:45

标签: haskell hugs

在玩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

这是Hugs中的错误吗?

2 个答案:

答案 0 :(得分:7)

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

为了避免在代码中消除数字文字的歧义,Haskell使用type defaulting为任何无约束的数字类型选择合理的具体类型。在这种情况下,这将是Integer。差异似乎是Hugs中的:type在此之前报告推断类型,而GHCi在应用类型默认后报告类型。

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

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

答案 1 :(得分:3)

这是一种推测,但这可能与(^)的类型有关。 ghci中的:t (^)返回(^) :: (Num a, Integral b) => a -> b -> a。我猜测拥抱看到^的第二个参数需要是Integral,即使该参数只是一个常数2,它也包含类型签名中的约束。

相关问题