Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Haskell appear to default to reading Int when reading Num?

I didn't expect the following code to work:

foo :: (Num a) => a -> a
foo x = x + x

main = do
    print (foo (read "7"))

because it is not possible to fully infer the type of (read "7") based on the code. But GHC (6.12.3) thinks otherwise and prints 14.

If "7" is changed to "7.2", the code fails with "no parse". What's going on here? how is Haskell deciding which instance of Read to use?

like image 669
Owen Avatar asked May 28 '11 23:05

Owen


2 Answers

This is caused by Haskell's defaulting rules for the Num class. If you added

default (Double, Integer)

to the top of your file, then you'd get the following results:

main = do
  print (foo (read "7")) -- prints "14.0"
  print (foo (read "7.2")) -- prints "14.2"

In a nutshell, defaulting rules are an attempt to "try to do the right thing" and save you from a compile error when you have an ambiguous type in your program. Unfortunately in this case it trades a compile-time error for a runtime error.

You can disable defaulting like so:

default ()

which will force you to explicitly disambiguate the types of such terms via type annotations:

print (foo (read "7" :: Int))
like image 160
Tom Crockett Avatar answered Nov 10 '22 15:11

Tom Crockett


Int is the default type in this instance. See sec. 6.3, Ambiguity and Type Defaulting, in A History of Haskell: Being Lazy with Class,

like image 36
rickythesk8r Avatar answered Nov 10 '22 15:11

rickythesk8r