Aelin
Aelin

Reputation: 301

Haskell recursive function to read input from user until a condition, and then return the input as list

I'm making a function readUntil that reads lines from user. Reading stops when f returns True for a line. Then the lines are returned as a list (the line that returned True is not included in that list). Here's what I have at the moment (some really raw/pseudo code now, excuse me):

readUntil :: (String -> Bool) -> IO [String]
readUntil f = fmap reverse (go []) where
    go xs = do
    x <- getLine
    if f = True then return xs
                else go (x : xs)

I would also like to make readUntil recursive (or implement a recursive helper function).

Upvotes: 1

Views: 1078

Answers (1)

rprospero
rprospero

Reputation: 961

I've included a small example below. You're pretty much at the solution. The important bit is just remembering how you'd generate a non-monad recusive list, then just putting that in the monad.

collectUntil :: (Monad m) => m a -> (a -> Bool) -> m [a]
collectUntil act f = do
  x <- act
  if f x
    then return []
    else (x:) <$> collectUntil act f

readUntil :: (String -> Bool) -> IO [String]
readUntil = collectUntil getLine

Upvotes: 1

Related Questions