Commit 44644ebe by simonpj

### [project @ 2005-03-09 10:54:57 by simonpj]

`Add notes about implicit parameters; pls merge`
parent d04c4288
 ... ... @@ -2107,6 +2107,68 @@ the binding for ?x, so the type of f is Implicit parameters and polymorphic recursion Consider these two definitions: len1 :: [a] -> Int len1 xs = let ?acc = 0 in len_acc1 xs len_acc1 [] = ?acc len_acc1 (x:xs) = let ?acc = ?acc + (1::Int) in len_acc1 xs ------------ len2 :: [a] -> Int len2 xs = let ?acc = 0 in len_acc2 xs len_acc2 :: (?acc :: Int) => [a] -> Int len_acc2 [] = ?acc len_acc2 (x:xs) = let ?acc = ?acc + (1::Int) in len_acc2 xs The only difference between the two groups is that in the second group len_acc is given a type signature. In the former case, len_acc1 is monomorphic in its own right-hand side, so the implicit parameter ?acc is not passed to the recursive call. In the latter case, because len_acc2 has a type signature, the recursive call is made to the polymoprhic version, which takes ?acc as an implicit parameter. So we get the following results in GHCi: Prog> len1 "hello" 0 Prog> len2 "hello" 5 Adding a type signature dramatically changes the result! This is a rather counter-intuitive phenomenon, worth watching out for. Implicit parameters and monomorphism GHC applies the dreaded Monomorphism Restriction (section 4.5.5 of the Haskell Report) to implicit parameters. For example, consider: f :: Int -> Int f v = let ?x = 0 in let y = ?x + v in let ?x = 5 in y Since the binding for y falls under the Monomorphism Restriction it is not generalised, so the type of y is simply Int, not (?x::Int) => Int. Hence, (f 9) returns result 9. If you add a type signature for y, then y will get type (?x::Int) => Int, so the occurrence of y in the body of the let will see the inner binding of ?x, so (f 9) will return 14. ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!