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 中的错误吗?
Came across this while playing with Haskell and I'm stumped:
Hugs> :type (\x -> x^2)
\x -> x ^ 2 :: (Integral a, Num b) => b -> b
What is a
doing in there? How am I supposed to read that? If I type the same thing into GHCi, it gives me the output I would expect:
Prelude> :type (\x -> x^2)
(\x -> x^2) :: Num a => a -> a
Is this a bug in Hugs?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Integral
约束来自2
的指数。请记住,在 Haskell 中,整数文字实际上是Num a => 类型的多态值。一个。然后编译器推断,因为它被用作
(^) :: (Num a, Integral b) => 的指数。一个-> b-> a
,它必须是更受约束的类型Integral a =>;一个。
为了使您不必消除代码中数字文字的歧义,Haskell 使用 类型默认< /a> 为任何不受约束的数字类型选择合理的具体类型。在本例中,该值为
Integer
。区别似乎在于 Hugs 中的:type
报告发生此情况之前推断的类型,而 GHCi 则报告应用类型默认后的类型。如果您自己为指数指定具体类型,则额外的约束就会消失。
The
Integral
constraint comes from the exponent of2
. Remember that in Haskell, integer literals are actually polymorphic values of typeNum a => a
. The compiler then infers that since it's being used as an exponent to(^) :: (Num a, Integral b) => a -> b -> a
, it must be of the more constrained typeIntegral a => a
.To save you from having to disambiguate numeric literals all over your code, Haskell uses type defaulting to pick a reasonable concrete type for any unconstrained numeric types. In this case, that will be
Integer
. The difference seems to be that:type
in Hugs reports the inferred type before this happens, while GHCi reports the type after type defaulting has been applied.If you specify a concrete type for the exponent yourself, the extra constraint disappears.
这是一种猜测,但这可能与
(^)
的类型有关。 ghci 中的:t (^)
返回(^) :: (Num a, Integral b) =>;一个-> b->一个。我猜拥抱看到
^
的第二个参数需要是一个Integral
,即使该参数只是一个常量 2,它也包含类型中的约束签名。This is sort of speculation, but this might have to do with the type of
(^)
.:t (^)
in ghci returns(^) :: (Num a, Integral b) => a -> b -> a
. I'm guessing hugs sees that the second argument of^
needs to be anIntegral
, and even though that argument is just a constant 2, it includes the constraint in the type signature.