Skip to content

Commit 5b7e88e

Browse files
committed
stack-safe foldl
1 parent 8517996 commit 5b7e88e

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

src/Control/Monad/List/Trans.purs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import Control.Alternative (class Alternative)
3939
import Control.Monad.Eff.Class (class MonadEff, liftEff)
4040
import Control.Monad.Trans.Class (class MonadTrans, lift)
4141
import Control.MonadPlus (class MonadPlus)
42+
import Control.Monad.Rec.Class as MR
4243
import Control.MonadZero (class MonadZero)
4344
import Control.Plus (class Plus)
4445

@@ -204,12 +205,14 @@ foldl' f = loop where
204205
g (Just (Tuple a as)) = (f b a) >>= (flip loop as)
205206

206207
-- | Fold a list from the left, accumulating the result using the specified function.
207-
foldl :: forall f a b. Monad f => (b -> a -> b) -> b -> ListT f a -> f b
208-
foldl f = loop where
209-
loop b l = uncons l >>= g
210-
where
211-
g Nothing = pure b
212-
g (Just (Tuple a as)) = loop (f b a) as
208+
foldl :: forall f a b. MR.MonadRec f => (b -> a -> b) -> b -> ListT f a -> f b
209+
foldl f b l = (MR.tailRecM2 loop) b l
210+
where
211+
loop :: b -> ListT f a -> f (MR.Step {a :: b, b :: ListT f a} b)
212+
loop accum l' = uncons l' >>= g
213+
where
214+
g Nothing = pure (MR.Done accum)
215+
g (Just (Tuple a as)) = pure (MR.Loop {a: f accum a, b: as})
213216

214217
-- | Fold a list from the left, accumulating the list of results using the specified function.
215218
scanl :: forall f a b. Monad f => (b -> a -> b) -> b -> ListT f a -> ListT f b

0 commit comments

Comments
 (0)