Commit 3d51f271 authored by twanvl's avatar twanvl Committed by Simon Peyton Jones
Browse files

Added note explaining the lambdas generated by functor deriving code, and how...

Added note explaining the lambdas generated by functor deriving code, and how it compares to the old deriving code which used eta expansion.
parent 49ca2a37
......@@ -1474,6 +1474,24 @@ This is pretty much the same as $fmap, only without the $(cofmap 'a 'a) case:
$(cofmap 'a '(T b1 b2)) = fmap $(cofmap 'a 'b2) -- when a only occurs in the last parameter, b2
$(cofmap 'a '(b -> c)) = \x b -> $(cofmap 'a' 'c) (x ($(fmap 'a 'c) b))
Note that the code produced by $(fmap _ _) is always a higher order function,
with type `(a -> b) -> (g a -> g b)` for some g. When we need to do pattern
matching on the type, this means create a lambda function (see the (,) case above).
The resulting code for fmap can look a bit weird, for example:
data X a = X (a,Int)
-- generated instance
instance Functor X where
fmap f (X x) = (\y -> case y of (x1,x2) -> X (f x1, (\z -> z) x2)) x
The optimizer should be able to simplify this code by simple inlining.
An older version of the deriving code tried to avoid these applied
lambda functions by producing a meta level function. But the function to
be mapped, `f`, is a function on the code level, not on the meta level,
so it was eta expanded to `\x -> [| f $x |]`. This resulted in too much eta expansion.
It is better to produce too many lambdas than to eta expand, see ticket #7436.
\begin{code}
gen_Functor_binds :: SrcSpan -> TyCon -> (LHsBinds RdrName, BagDerivStuff)
gen_Functor_binds loc tycon
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment