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: 
1464  1464  $(cofmap 'a '(T b1 b2)) = fmap $(cofmap 'a 'b2)  when a only occurs in the last parameter, b2 
1465  1465  $(cofmap 'a '(b > c)) = \x b > $(cofmap 'a' 'c) (x ($(fmap 'a 'c) b)) 
1466  1466  
 1467  Note that the code produced by $(fmap _ _) is always a higher order function, 
 1468  with type `(a > b) > (g a > g b)` for some g. When we need to do pattern 
 1469  matching on the type, this means create a lambda function (see the (,) case above). 
 1470  The resulting code for fmap can look a bit weird, for example: 
 1471  
 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 
 1476  
 1477  The optimizer should be able to simplify this code by simple inlining. 
 1478  
 1479  An older version of the deriving code tried to avoid these applied 
 1480  lambda functions by producing a meta level function. But the function to 
 1481  be mapped, `f`, is a function on the code level, not on the meta level, 
 1482  so it was eta expanded to `\x > [ f $x ]`. This resulted in too much eta expansion. 
 1483  It is better to produce too many lambdas than to eta expand, see ticket #7436. 
 1484  
1467  1485  \begin{code} 
1468  1486  gen_Functor_binds :: SrcSpan > TyCon > (LHsBinds RdrName, BagDerivStuff) 
1469  1487  gen_Functor_binds loc tycon 