conduit icon indicating copy to clipboard operation
conduit copied to clipboard

[RFC] foldWhile

Open ocramz opened this issue 5 years ago • 3 comments

A specialized version of mapAccumWhile that keeps folding as long as the function argument returns 'Right'

foldWhile :: (Monad m) => (a -> s -> Either s s) -> s -> C.ConduitT a o m s
foldWhile f = loop
  where
    loop !s = C.await >>= maybe (pure s) go
      where
        go a = either (return $!) loop $ f a s

ocramz avatar Nov 08 '20 08:11 ocramz

I found a need for this while writing a family of stochastic gradient descent algorithms; the conduit processes one data point of type a at a time and stops accumulating state when a convergence or divergence criterion is met.

ocramz avatar Nov 08 '20 09:11 ocramz

Seems reasonable to me. Only complaint I can think of: it hides away information about whether it was an end-of-stream versus a Left value produced by f. It may make more sense to generalize a bit to:

foldWhile :: Monad m => (a -> s -> Either e s) -> s -> ConduitT a o m (Either e s)

Either with fmap (either id id) you recover the original behavior. Thoughts?

snoyberg avatar Nov 08 '20 09:11 snoyberg

Indeed, your version of foldWhile is clearer. I'll prepare a PR!

ocramz avatar Nov 08 '20 10:11 ocramz