commit 640b50f710df5310d6e3f6cede66b776d9c09cc2
Author: Simon Peyton Jones <[email protected]>
Date: Fri Jan 18 17:39:33 2013 +0000
Use cheapBuild for enumerations; and fusion rules for cheapBuild
Modified GHC/Base.lhs
diff git a/GHC/Base.lhs b/GHC/Base.lhs
index 075f21d..fe3dc23 100644
a

b

build :: forall a. (forall b. (a > b > b) > b > b) > [a] 
306  306  
307  307  build g = g (:) [] 
308  308  
 309  cheapBuild :: forall a. (forall b. (a > b > b) > b > b) > [a] 
 310  {# INLINE CONLIKE [1] cheapBuild #} 
 311   cheapBuild is just like build, except that it is CONLIKE 
 312   See Note [cheapBuild] 
 313  cheapBuild g = g (:) [] 
 314  
309  315    A list producer that can be fused with 'foldr'. 
310  316   This function is merely 
311  317   
… 
… 
augment g xs = g (:) xs 
322  328  {# RULES 
323  329  "fold/build" forall k z (g::forall b. (a>b>b) > b > b) . 
324  330  foldr k z (build g) = g k z 
 331  "fold/cheapBuild" forall k z (g::forall b. (a>b>b) > b > b) . 
 332  foldr k z (cheapBuild g) = g k z 
325  333  
326  334  "foldr/augment" forall k z xs (g::forall b. (a>b>b) > b > b) . 
327  335  foldr k z (augment g xs) = g k (foldr k z xs) 
328  336  
 337  "augment/cheapBuild" forall (g::forall b. (a>b>b) > b > b) 
 338  (h::forall b. (a>b>b) > b > b) . 
 339  augment g (cheapBuild h) = build (\c n > g c (h c n)) 
 340   'augment' doesn't necessarily have a cheap argument, so we revert to 'build' 
 341  
329  342  "foldr/id" foldr (:) [] = \x > x 
330  343  "foldr/app" [1] forall ys. foldr (:) ys = \xs > xs ++ ys 
331  344   Only activate this from phase 1, because that's 
… 
… 
augment g xs = g (:) xs 
353  366   augment g (augment h t) = augment (\cn > g c (h c n)) t 
354  367  \end{code} 
355  368  
 369  Note [cheapBuild] 
 370  ~~~~~~~~~~~~~~~~~ 
 371  cheapBuild is just like build, except that it is CONLIKE 
 372  
 373  It is used in situations where fusion is more imortant than sharing, 
 374  ie in situation where its argument function 'g' in (cheapBuild g) is 
 375  cheap. 
 376  
 377  Main example: enumerations of one kind or another: 
 378  f x = let xs = [x..] 
 379  go = \y. ....go y'....(map (h y) xs)... 
 380  in ... 
 381  Here we woud like to fuse the map with the [x..] 
356  382  
357  383   
358  384   map 
… 
… 
a `iShiftRL#` b  b >=# WORD_SIZE_IN_BITS# = 0# 
715  741  
716  742   Rules for C strings (the functions themselves are now in GHC.CString) 
717  743  {# RULES 
718   "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) 
 744  "unpack" [~1] forall a . unpackCString# a = cheapBuild (unpackFoldrCString# a) 
719  745  "unpacklist" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a 
720  746  "unpackappend" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n 
721  747  
Modified GHC/Enum.lhs
diff git a/GHC/Enum.lhs b/GHC/Enum.lhs
index 625214a..928fd6c 100644
a

b

instance Enum Char where 
376  376  enumFromThenTo (C# x1) (C# x2) (C# y) = efdtChar (ord# x1) (ord# x2) (ord# y) 
377  377  
378  378  {# RULES 
379   "eftChar" [~1] forall x y. eftChar x y = build (\c n > eftCharFB c n x y) 
380   "efdChar" [~1] forall x1 x2. efdChar x1 x2 = build (\ c n > efdCharFB c n x1 x2) 
381   "efdtChar" [~1] forall x1 x2 l. efdtChar x1 x2 l = build (\ c n > efdtCharFB c n x1 x2 l) 
 379  "eftChar" [~1] forall x y. eftChar x y = cheapBuild (\c n > eftCharFB c n x y) 
 380  "efdChar" [~1] forall x1 x2. efdChar x1 x2 = cheapBuild (\ c n > efdCharFB c n x1 x2) 
 381  "efdtChar" [~1] forall x1 x2 l. efdtChar x1 x2 l = cheapBuild (\ c n > efdtCharFB c n x1 x2 l) 
382  382  "eftCharList" [1] eftCharFB (:) [] = eftChar 
383  383  "efdCharList" [1] efdCharFB (:) [] = efdChar 
384  384  "efdtCharList" [1] efdtCharFB (:) [] = efdtChar 
… 
… 
instance Enum Int where 
511  511   In particular, we have rules for deforestation 
512  512  
513  513  {# RULES 
514   "eftInt" [~1] forall x y. eftInt x y = build (\ c n > eftIntFB c n x y) 
 514  "eftInt" [~1] forall x y. eftInt x y = cheapBuild (\ c n > eftIntFB c n x y) 
515  515  "eftIntList" [1] eftIntFB (:) [] = eftInt 
516  516  #} 
517  517  
… 
… 
eftIntFB c n x0 y  x0 ># y = n 
541  541  
542  542  {# RULES 
543  543  "efdtInt" [~1] forall x1 x2 y. 
544   efdtInt x1 x2 y = build (\ c n > efdtIntFB c n x1 x2 y) 
 544  efdtInt x1 x2 y = cheapBuild (\ c n > efdtIntFB c n x1 x2 y) 
545  545  "efdtIntUpList" [1] efdtIntFB (:) [] = efdtInt 
546  546  #} 
547  547  
… 
… 
instance Enum Integer where 
669  669  enumFromThenTo x y lim = enumDeltaToInteger x (yx) lim 
670  670  
671  671  {# RULES 
 672   We don't use cheapBuild for Integer 
672  673  "enumDeltaInteger" [~1] forall x y. enumDeltaInteger x y = build (\c _ > enumDeltaIntegerFB c x y) 
673  674  "efdtInteger" [~1] forall x y l.enumDeltaToInteger x y l = build (\c n > enumDeltaToIntegerFB c n x y l) 
674  675  "enumDeltaInteger" [1] enumDeltaIntegerFB (:) = enumDeltaInteger 