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?
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.