On 20 Sep 2006, at 17:28, Christian Sievers 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.
Thanks - that's a helpful example. But why is the following not equivalent to the untyped "k = 2" case: let f :: Int -> Int -> Int ; f x y = x * y in (f 2 2, 1/2) Does the type of 2 effectively get decided twice, once as an Int, and once as a Fractional, and is this the "repeated computation" that the monomorphism restriction is intended to prevent? Otherwise, I would have expected that it wouldn't make any difference whether I used a named 2 or an anonymous 2, but imposing the monomorphism restriction on the named 2 seems to break referential transparency. Thanks. Robert