diff --git a/src/Data/List/Lazy.purs b/src/Data/List/Lazy.purs index 4b0b222..69f80aa 100644 --- a/src/Data/List/Lazy.purs +++ b/src/Data/List/Lazy.purs @@ -86,6 +86,7 @@ module Data.List.Lazy , transpose , foldM + , foldrLazy , module Exports ) where @@ -716,3 +717,11 @@ foldM f a xs = Nothing -> pure a Just { head: b, tail: bs } -> f a b >>= \a' -> foldM f a' bs + +-- | Perform a right fold lazily +foldrLazy :: forall a b. Z.Lazy b => (a -> b -> b) -> b -> List a -> b +foldrLazy op z = go + where + go xs = case step xs of + Cons x xs' -> Z.defer \_ -> x `op` go xs' + Nil -> z diff --git a/test/Test/Data/List/Lazy.purs b/test/Test/Data/List/Lazy.purs index f3e0a2b..d29ea11 100644 --- a/test/Test/Data/List/Lazy.purs +++ b/test/Test/Data/List/Lazy.purs @@ -7,7 +7,7 @@ import Control.Monad.Eff (Eff) import Control.Monad.Eff.Console (CONSOLE, log) import Data.Lazy as Z -import Data.List.Lazy (List, nil, cons, foldl, foldr, foldMap, singleton, transpose, take, iterate, filter, uncons, foldM, range, unzip, zip, length, zipWithA, replicate, repeat, zipWith, intersectBy, intersect, deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group, partition, span, dropWhile, drop, takeWhile, slice, catMaybes, mapMaybe, filterM, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, init, tail, last, head, insertBy, insert, snoc, null, replicateM, fromFoldable, (:), (\\), (!!)) +import Data.List.Lazy (List, nil, cons, foldl, foldr, foldMap, singleton, transpose, take, iterate, filter, uncons, foldM, foldrLazy, range, unzip, zip, length, zipWithA, replicate, repeat, zipWith, intersectBy, intersect, deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group, partition, span, dropWhile, drop, takeWhile, slice, catMaybes, mapMaybe, filterM, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, init, tail, last, head, insertBy, insert, snoc, null, replicateM, fromFoldable, (:), (\\), (!!)) import Data.List.Lazy.NonEmpty as NEL import Data.Maybe (Maybe(..), isNothing, fromJust) import Data.Monoid.Additive (Additive(..)) @@ -339,6 +339,10 @@ testListLazy = do f acc x = if x >= 10 then Nothing else Just (cons 0 acc) in foldM f nil infs == Nothing + log "foldrLazy should work ok on infinite lists" + assert let infs = iterate (_ + 1) 1 + infs' = foldrLazy cons nil infs + in take 1000 infs == take 1000 infs' log "can find the first 10 primes using lazy lists" let eratos :: List Int -> List Int