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.
What's a typeclass in Haskell? A typeclass defines a set of methods that is shared across multiple types. For a type to belong to a typeclass, it needs to implement the methods of that typeclass. These implementations are ad-hoc: methods can have different implementations for different types.
Num is a typeclass — a group of types — which includes all types which are regarded as numbers. The (Num a) => part of the signature restricts a to number types – or, in Haskell terminology, instances of Num .
In Haskell, type classes provide a structured way to control ad hoc polymorphism, or overloading. [For the stylistic reason we discussed in Section 3.1, we have chosen to define elem in infix form. == and || are the infix operators for equality and logical or, respectively.]
An instance of a class is an individual object which belongs to that class. In Haskell, the class system is (roughly speaking) a way to group similar types. (This is the reason we call them "type classes"). An instance of a class is an individual type which belongs to that class.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With