Why is partition no good list producer?

Hi all, I'm about to optimize a fairly large Haskell program, which uses partition quite often (and a fold immediately afterwards). The GHC User guide section about RULE pragmas says that filter is a good producer, whereas partition is not mentioned (therefore, I assume it is not). I put a little test program together:
fuse1 :: [Bool] -> (Bool,Bool) fuse1 xs = (x,y) where (fs,gs) = partition id xs x = foldr (&&) True fs y = foldr (||) False gs
fuse2 :: [Bool] -> (Bool,Bool) fuse2 xs = (x,y) where fs = filter id xs gs = filter not xs x = foldr (&&) True fs y = foldr (||) False gs
Compiling it via ghc -O and loading the compiled object to ghci results in: Prelude Test> fuse2 (replicate 10000000 False) (True,False) (8.19 secs, 241174592 bytes) Prelude Test> fuse1 (replicate 10000000 False) (*** Exception: stack overflow (6.18 secs, 48472660 bytes) I understand the results: Using partition an intermediate list seems to be build. But WHY? Is it simply because of a missing RULE pragma for partition or is there a "deeper" reason? Cheers, Jan

Jan Scheffczyk wrote:
I'm about to optimize a fairly large Haskell program, which uses partition quite often (and a fold immediately afterwards). The GHC User guide section about RULE pragmas says that filter is a good producer, whereas partition is not mentioned (therefore, I assume it is not).
what you observe is possibly related to this: http://www.mail-archive.com/haskell@haskell.org/msg07508.html -- -- Johannes Waldmann, Tel/Fax: (0341) 3076 6479 / 6480 -- ------ http://www.imn.htwk-leipzig.de/~waldmann/ ---------

what you observe is possibly related to this:
http://www.mail-archive.com/haskell@haskell.org/msg07508.html
Although I'm adressing purely the problem of runtime, you are probably right. At least the implementation of partition is still defined in terms of foldr (from Data.List in ghc 6.2): -- > partition p xs == (filter p xs, filter (not . p) xs) partition :: (a -> Bool) -> [a] -> ([a],[a]) {-# INLINE partition #-} partition p xs = foldr (select p) ([],[]) xs select p x (ts,fs) | p x = (x:ts,fs) | otherwise = (ts, x:fs) Is the above strict version of partition more suitable for other optimizations than my partition/foldr case?? Cheers, Jan
participants (2)
-
Jan Scheffczyk
-
Johannes Waldmann