[Haskell-cafe] IO, sequence, lazyness, takeWhile

Luke Palmer lrpalmer at gmail.com
Mon Dec 13 15:50:41 CET 2010


On Mon, Dec 13, 2010 at 7:15 AM, Jacek Generowicz
<jacek.generowicz at cern.ch> wrote:
> -- Is it possible to rewrite code written in this style
>
> untilQuit = do
>  text <- getLine
>  report text
>  if text == "quit"
>     then return ()
>     else untilQuit
>
> -- in a style using higher order functions for abstract iteration? For
> -- example, something along these lines:
>
> untilQuit' = (fmap (takeWhile (/= "quit"))) (sequence $ map (>>= report)
> (repeat getLine))

You are asking about standard library functions?  Probably, but I
think it is cleanest to just write a HOF to encapsulate this pattern.
I have used this one before:

whileM_ :: (Monad m) => (a -> Bool) -> m a -> m ()
whileM_ p m = bool (return ()) (whileM p m) . p =<< m

bool :: a -> a -> Bool -> a
bool t f True = t
bool t f False = f

untilQuit = whileM_ (/= "quit") (getLine >>= liftM2 (>>) report return)

I find a variant of whileM that returns m [a] particularly handy for
collecting events in an event loop.

Luke



More information about the Haskell-Cafe mailing list