I am learning Haskell at Uni this semester. I encountered a problem where I have a list of lists as IO [[String]]
and I want to append an IO [String]
to the first one.
Lets denote them as x and y. So I tried doing y >>= return . ( ) [x]
or y <> [x]
. All of them gave the error: Could not match IO [[String]] with [IO [String]].
Any suggestions? Thank you.
CodePudding user response:
In my opinion, the simplest general technique to learn is about how to use do
blocks.
test :: IO [[String]]
test = do
xss <- generateListOfLists -- IO [[String]]
xs <- generateList -- IO [String]
return (xss [xs])
The idea is that <-
temporarily unwraps the monad, removing the IO
monad from types, as long as at the very end we return a value in the same monad (the return
at the end).
After one understands that general technique, one can then learn alternatives like applicative notation, which is not as general, but still nice.
test :: IO [[String]]
test =
(\xss xs -> xss [xs])
<$> generateListOfLists
<*> generateList
Using >>=
is less common, and at least in this case, less convenient than a do
block.
test :: IO [[String]]
test =
generateListOfLists >>= \xss ->
generateList >>= \xs ->
return (xss [xs])