Skip to content

Data.Either.partitionEithers is not lazy enough

Data.Either.partitionEithers gives a stack overflow for long or infinite lists.

Change

partitionEithers :: [Either a b] -> ([a],[b])
partitionEithers = foldr (either left right) ([],[])
 where
  left  a (l, r) = (a:l, r)
  right a (l, r) = (l, a:r)

to

partitionEithers :: [Either a b] -> ([a],[b])
partitionEithers = foldr (either left right) ([],[])
 where
  left  a ~(l, r) = (a:l, r)
  right a ~(l, r) = (l, a:r)

to make it lazy enough.

Example:

Data.Either> let fun k = case gcd k 15 of { 3 -> Left "Fizz"; 5 -> Left "Buzz"; 15 -> Left "FizzBuzz"; _ -> Right k }
Data.Either> take 10 . snd . partitionEithers $ map fun [1 .. 2*10^6 :: Integer]
*** Exception: stack overflow
Data.Either> take 10 . snd . lpartitionEithers $ map fun [1 :: Integer .. ]
[1,2,4,7,8,11,13,14,16,17]
Trac metadata
Trac field Value
Version 6.10.4
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/base
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information