• ## compiler/typecheck/TcGenDeriv.lhs

From 5423500f92626728284c61cb2f017ecd53c40381 Mon Sep 17 00:00:00 2001
From: Twan van Laarhoven <[email protected]
/* <![CDATA[ */!function(){try{var t="currentScript"in document?document.currentScript:function(){for(var t=document.getElementsByTagName("script"),e=t.length;e--;)if(t[e].getAttribute("cf-hash"))return t[e]}();if(t&&t.previousSibling){var e,r,n,i,c=t.previousSibling,a=c.getAttribute("data-cfemail");if(a){for(e="",r=parseInt(a.substr(0,2),16),n=2;a.length-n;n+=2)i=parseInt(a.substr(n,2),16)^r,e+=String.fromCharCode(i);e=document.createTextNode(e),c.parentNode.replaceChild(e,c)}}}catch(u){}}();/* ]]> */>
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 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