Arie Peterson wrote:
However, if I type an apparently equivalent let expression into Hugs directly, then I get the value 4 as expected
let k = 2 ; f :: Int -> Int -> Int ; f x y = x * y in f k k
Why is there a difference in behaviour?
Here, there is no defaulting, 'k' has the polymorphic type you expect, and the use of 'k' as an argument to the monomorphically typed 'f' chooses the right instance of 'Num'.
Well, there is no defaulting at the stage of type checking when k is given type Num a => a, the monomorphism restriction applies and this type is not generalised to forall a . (Num a) => a, then the use of k forces the type variable a to be Int, and then there is no longer any need for defaulting. So k gets a monotype which is determined by its usage, you cannot do e.g. let k = 2 ; f :: Int -> Int -> Int ; f x y = x * y in (f k k, 1/k) whereas let k :: Num a => a; k = 2; ... is possible. Defaulting in Haskell 98 happens so late that this file k = 2 f :: Int -> Int -> Int f x y = x * y r = f k k is okay. Alas, Hugs does not comply in this respect, see http://cvs.haskell.org/Hugs/pages/users_guide/haskell98.html at the end of 5.1.3. All the best, Christian Sievers