在玩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中的错误吗?
答案 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,它也包含类型签名中的约束。