Reputation: 3774
Can someone please explain what I am missing here:
Prelude> :t read
read :: (Read a) => String -> a
Prelude> read "4"
<interactive>:1:0:
Ambiguous type variable `a' in the constraint:
`Read a' arising from a use of `read' at <interactive>:1:0-7
Probable fix: add a type signature that fixes these type variable(s)
read "4"
raises an error as ghci doesn't know which concrete type we want, it only knows that we have a Read
type class. read "4" :: Int
works fine. This is clear to me.
Now, following the above logic, I expected fromIntegral 4
to raise an error:
Prelude> :t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b
Prelude> fromIntegral 4
4
However, it works fine. Why is a type annotaion NOT required in this case? I expected the above to fail; and ONLY
Prelude> fromIntegral 4 :: Int
to work.
NB - I am reading "Learn you a Haskell for great good" and have covered till chapter 5. Is what I am asking discussed in chapter 7 (or some other chapter)?
Thanks.
Upvotes: 8
Views: 163
Reputation: 139930
It works because of type defaulting, which causes ambiguous type variables to be defaulted to Integer
or Double
(or some other user-defined default). This only happens for Num
and its subclasses.
In GHCi, the rules for defaulting are relaxed to also work for Show
, Eq
and Ord
, and also ()
is added to the list of default types. This allows expressions like [] == []
to type check.
Upvotes: 12
Reputation: 36339
Difference is that read could potentially result in any type, whereas fromIntegral yields a number. There is some defaulting going on with regard to numbers in ghci, so that ghci can just use the default type.
Upvotes: 4