Ticket #7436: 0002-Added-note-explaining-the-lambdas-generated-by-funct.patch

File 0002-Added-note-explaining-the-lambdas-generated-by-funct.patch, 1.9 KB (added by twanvl, 2 years ago)
  • compiler/typecheck/TcGenDeriv.lhs

    From 5423500f92626728284c61cb2f017ecd53c40381 Mon Sep 17 00:00:00 2001
    From: Twan van Laarhoven <[email protected]>
    Date: Thu, 3 Jan 2013 16:24:42 +0100
    Subject: [PATCH 2/2] 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 f8c40b3..f6c00fa 100644
    a b This is pretty much the same as $fmap, only without the $(cofmap 'a 'a) case: 
    14641464  $(cofmap 'a '(T b1 b2))  =  fmap $(cofmap 'a 'b2)   -- when a only occurs in the last parameter, b2 
    14651465  $(cofmap 'a '(b -> c))   =  \x b -> $(cofmap 'a' 'c) (x ($(fmap 'a 'c) b)) 
     1467Note that the code produced by $(fmap _ _) is always a higher order function, 
     1468with type `(a -> b) -> (g a -> g b)` for some g. When we need to do pattern 
     1469matching on the type, this means create a lambda function (see the (,) case above). 
     1470The resulting code for fmap can look a bit weird, for example: 
     1472  data X a = X (a,Int) 
     1473  -- generated instance 
     1474  instance Functor X where 
     1475      fmap f (X x) = (\y -> case y of (x1,x2) -> X (f x1, (\z -> z) x2)) x 
     1477The optimizer should be able to simplify this code by simple inlining. 
     1479An older version of the deriving code tried to avoid these applied 
     1480lambda functions by producing a meta level function. But the function to 
     1481be mapped, `f`, is a function on the code level, not on the meta level, 
     1482so it was eta expanded to `\x -> [| f $x |]`. This resulted in too much eta expansion. 
     1483It is better to produce too many lambdas than to eta expand, see ticket #7436. 
    14681486gen_Functor_binds :: SrcSpan -> TyCon -> (LHsBinds RdrName, BagDerivStuff) 
    14691487gen_Functor_binds loc tycon