Repository : ssh://darcs.haskell.org//srv/darcs/ghc On branch : master
http://hackage.haskell.org/trac/ghc/changeset/3d51f271e6819c52508956f2426c4c19dec0b2fb >--------------------------------------------------------------- commit 3d51f271e6819c52508956f2426c4c19dec0b2fb Author: Twan van Laarhoven <twa...@gmail.com> Date: Thu Jan 3 16:24:42 2013 +0100 Added note explaining the lambdas generated by functor deriving code, and how it compares to the old deriving code which used eta expansion. >--------------------------------------------------------------- compiler/typecheck/TcGenDeriv.lhs | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/compiler/typecheck/TcGenDeriv.lhs b/compiler/typecheck/TcGenDeriv.lhs index c643c6b..32f3a15 100644 --- a/compiler/typecheck/TcGenDeriv.lhs +++ b/compiler/typecheck/TcGenDeriv.lhs @@ -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 _______________________________________________ Cvs-ghc mailing list Cvs-ghc@haskell.org http://www.haskell.org/mailman/listinfo/cvs-ghc