Haskell Method for Combining [IO String] into an I / O String

My goal is to write a Haskell function that reads N lines from input and combines them into one line. The following is the first attempt:

readNLines :: Int -> IO String readNLines n = do let rows = replicate n getLine let rowsAsString = foldl ++ [] rows return rowsAsString 

Here haskell complains about foldl :

Failed to match expected type [a]' against inferred type (a1 β†’ b β†’ a1) β†’ a1 β†’ [b] β†’ a1'

As I understand it, the type of strings is [IO String] , is it possible to somehow join such a list in one IO String ?

+4
source share
5 answers

Besides what the ephemer indicates, I think you have a syntax problem: the way you use the ++ operator makes it look like you are trying to call the ++ operator with the foldl and [] operands. Put the ++ operator in parentheses to make your intention clear:

 foldl (++) [] rows 
+6
source

The functions you are looking for are sequence , however it should be noted that

 sequence (replicate nf) 

coincides with

 replicateM nf 

And foldl (++) [] equivalent to concat . So your function:

 readNLines n = liftM concat (replicateM n getLine) 

Alternatively, if you want to keep line breaks:

 readNLines n = liftM unlines (replicateM n getLine) 
+5
source

The shortest answer I can come up with is:

 import Control.Applicative import Control.Monad readNLines :: Int -> IO String readNLines n = concat <$> replicateM n getLine 
+1
source

replicate returns a list of IO String actions. To complete these steps, they must be run in the IO monad. Therefore, you do not want to join the array of I / O operations, but simply run them sequentially and return the result.

Here is what i will do

 readNLines :: Int -> IO String readNLines n = do lines <- replicateM n getLine return $ concat lines 

Or in the applicative style:

 import Control.Applicative readNLines :: Int -> IO String readNLines n = concat <$> replicateM n getLine 

Both of them use monadic replication (replicateM), which evaluates a list of monadic values ​​in a sequence, and not just returns a list of actions

0
source

All Articles