Unexpected list non-fusion

Simon Peyton-Jones simonpj at microsoft.com
Thu Dec 15 18:38:41 CET 2011


| Am Montag, den 12.12.2011, 15:37 -0500 schrieb wren ng thornton:
| > I've noticed that take and filter are good producers (and consumers)
| > for list fusion, but takeWhile, drop, and dropWhile are not. Is there
| > any reason for this discrepancy?
| >
| > If not, would I need to go through the libraries@ process for fixing
| > it, or should I just submit a patch?

Please just submit a patch.

| while preparing my guest lecture¹ about Haskell Performance recently I also
| noticed that takeWhile (and concatMap!) are not setup for list fusion, here
| is what I showed the students; it improved performance considerably in the
| testcase.
| 
| takeWhile' :: (a -> Bool) -> [a] -> [a]
| takeWhile' p xs = build $ \c n -> foldr (takeWhileF p c n) n xs {-# INLINE
| takeWhile' #-}
| 
| takeWhileF p c n x xs = if p x then x `c` xs else n
| 
| Of course, for a proper inclusion one first has to find out if takeWhile' is
| sufficiently fast even when not fused, or whether one has to do the „replace
| first, try to fuse, and then try to replace back by original function if not
| fused“ tick that is used for, e.g., (++).

The latter approach is probably safer.  Follow the pattern for (++).

Thanks

Simon


More information about the Glasgow-haskell-users mailing list