Consider the following function
add1 :: Num a => a -> a
add1 x = x + 1
and the following applications
*Main> add1 2
3
*Main> add1 2.2
3.2
*Main> add1 (read "1")
2
add1 (read "1.5"::Float)
2.5
*Main> add1 (read "1.5")
*** Exception: Prelude.read: no parse
Why does the last invication of add1
fail for floating point numbers, while it works for integers? Why do I have to specify a type in that case?
GHCi gives it type
> :t add1 (read "1.5")
add1 (read "1.5") :: (Read a, Num a) => a
So, its still polymorphic. However, when evaluated in GHCi, it implicitly print
ed, so GHCi must pick some concrete type for a
. GHCi uses the defaulting rules, and statically chooses a = Integer
. Note that this choice is done statically (during type checking, roughly), and only depends on types (e.g. String
), not actual values (e.g. "1.5"
). Integer
is both a Read
and a Num
, so all static checks pass.
More in detail, GHCi tries types ()
, Integer
, Double
-- in that order, unless there is a default
declaration saying otherwise.
Then, at run-time the code behaves as
> add1 (read "1.5") :: Integer
*** Exception: Prelude.read: no parse
since the string can not be parsed. By comparison, this would be fine:
> add1 (read "1.5") :: Float
2.5
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