Functional programming with IO
Asking a question
ask :: String -> IO String
ask question = do
putStrLn question
getLine
GHCi> ask "What is your name?"
What is your name?
Andres
"Andres"
Asking many questions
askMany :: [String] -> IO [String]
askMany [] = return []
askMany (q : qs) = do
answer <- ask q
answers <- askMany qs
return (answer : answers)
The standard design pattern on lists is back!
Feels like a map
A map
has the wrong result type:
askMany' :: [String] -> [IO String]
askMany' = map ask
But we can sequence a list of plans:
sequence :: [IO a] -> IO [a]
sequence [] = return []
sequence (x : xs) = do
a <- x
as <- sequence xs
return (a : as)
Mapping an IO action
mapM :: (a -> IO b) -> [a] -> IO [b]
mapM f xs = sequence (map f xs)
askMany :: [String] -> IO [String]
askMany questions = mapM ask questions