Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regarding Haskell type classes (Num vs Read)

Tags:

haskell

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.

like image 741
babon Avatar asked Jul 05 '15 08:07

babon


People also ask

What are type classes in Haskell?

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.

What does NUM mean in Haskell?

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 .

What are type classes in Haskell What purpose do they serve?

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

What is an instance of a Haskell type class?

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.


2 Answers

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.

like image 146
hammar Avatar answered Sep 21 '22 20:09

hammar


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.

like image 37
Ingo Avatar answered Sep 20 '22 20:09

Ingo