1
votes

Can anybody explain, why it is valid to read a number to add it to a another number, although reading just a number is not valid?

Prelude> read "5" + 3
8
Prelude> read "5"

:33:1:
    No instance for (Read a0) arising from a use of `read'
    The type variable `a0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Read () -- Defined in `GHC.Read'
      instance (Read a, Read b) => Read (a, b) -- Defined in `GHC.Read'
      instance (Read a, Read b, Read c) => Read (a, b, c)
        -- Defined in `GHC.Read'
      ...plus 25 others
    In the expression: read "5"
    In an equation for `it': it = read "5"

Why is "5" ambiguous?

1

1 Answers

7
votes

"5" itself is not ambiguous, it's more that Haskell does not know to what type you want to read. read is a function defined as:

read :: Read a => String -> a

and you can define multiple types that support the Read class. For instance Int is an instance of Read, but also Float and you can define your own type that is an instance of Read. You could for instance have defined your own type:

data WeirdNumbers = Five | Twelve

and then define an instance Read WeirdNumbers where you map "5" on Five, etc. Now "5" thus maps on several types.

You can simply solve the problem by telling Haskell to what type you want to read. Like:

Prelude> read "5" :: Int
5
Prelude> read "5" :: Float
5.0

The reason why read "5" + 3 works by the way is because here you provide a 3 and a (+) :: Num a => a -> a -> a. So Haskell reasons "Well 3 is an Integer and + requires that the left and the right operand to be of the same type, I know I have to use read such that it reads to an Integer as well."