[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.
More information about the Haskell-Cafe
mailing list