This was prompted by Resolving the type of `f = f (<*>) pure`, which discusses a more complicated example, but this one works too.
The following definition compiles without problem:
w :: Integral a => a
w = fromInteger w
...Of course it doesn't work runtime-wise, but that's beside the question. The point is that the definition of w
itself uses a specialised version of w :: Integer
. Clearly that is a suitable instantiation, and therefore typechecks.
However, if we remove the signature, then GHC infers not the above type, but only the concrete one:
w' = fromInteger w'
GHCi> :t w
w :: Integral a => a
GHCi> :t w'
w' :: Integer
Well, when I saw this, I was fairly sure this was the monomorphism restriction at work. It's well known that also e.g.
i = 3
GHCi> :t i
i :: Integer
although i :: Num p => p
would be perfectly possible. And indeed, i :: Num p => p
is inferred if -XNoMonomorphismRestriction
is active, i.e. if the monomorphism restriction is disabled.
However, in case of w'
only the type Integer
is inferred even when the monomorphism restriction is disabled.
To count out that this has something to do with defaulting:
fromFloat :: RealFrac a => Float -> a
q :: RealFrac a => a
q = fromFloat q
q' = fromFloat q'
GHCi> :t q
q :: RealFrac a => a
GHCi> :t q'
q' :: Float
Why is the polymorphic type not inferred?
w' = fromInteger w'
, being recursive, is not simple)? – ArcadiafromInteger
has type(Num a) => Integer -> a
, and sincew'
is used as the input tofromInteger
, doesn't that meanInteger
is the only possible type for it? Indeed I'm rather surprised that the version with the polymorphic type signature compiles. (So as I said, probably missing something.) – KronfeldInteger
is certainly the only possible monomorphic type forw'
, but asw
demonstrates a polymorphic type is perfectly fine as well. After all, a polymorphic type can be instantiated to a monomorphic one, provided it fulfills the constraints. – Selfconceit