[Haskell-cafe] operations on lists with continuations

Evan Laforge qdunkan at gmail.com
Wed Mar 2 07:51:26 CET 2011

```I have a few functions for operating on lists that take continuations:

-- | Like takeWhile but with a continuation, so you can chain takes without
-- copying.
takeWhileThen :: (a -> Bool) -> ([a] -> [a]) -> [a] -> [a]
takeWhileThen _ _ [] = []
takeWhileThen f cont (x:xs)
| f x = x : takeWhileThen f cont xs
| otherwise = cont (x:xs)

But of course this isn't enough, then I start wanting a takeThen.  And
then a filterThen.  That makes me think plain explicit recursion would
be clearer, but the problem I have with that is that it has an
imperative feel.  What I mean by that is that the result is a product
of the changing state of the recursing function, and it's
non-composable.  E.g.

filterUntil start end msgs = go
where
go [] = []
go (m:ms)
| msg_start m >= start = takeWhile ((<end) . msg_start) (m : ms)
| condition m = m : go ms
| otherwise = go ms

Whereas with filterThen I can write:

filterUntil start end = filterThen condition ((>=start) . msg_start) .
takeWhile ((<end) . msg_start)

This looks much more functional to me, and can be composed:

filterUntilPlus1 start end = filterThen condition ((>=start) .
msg_start) \$ takeWhileThen ((<end) . msg_start) \$ take 1

So my question is, am I about to discover this already exists in the
Prelude, or is unnecessary because of something I'm overlooking?  I
imagine it must be a special case of some kind of generalization,
right?  Surely someone has thought of this and taken it much further
than I have.  I suppose this starts to look like maybe a CPS version
of a parser... but it seems lighter-weight for simple tasks.

```