Hi I have small problem with printing [[[Char]]]
using IO.
I have a [[[Char]]]
list - in another words [[String]]
I would like to print them like
FirstStringOfFirstListOfStrings
SecondStringOfFirstListOfStrings
.
.
.
LastStringOffFirstListofStrings
(some gap anything empty line "----" string anything)
FirstStringOfSecondsListOfStrings
In another words I don't want the [String]
to be printed one under another (one row break at least or some line filled with ------
for example)
mapM_ (mapM_ print)
My idea was to compose the (mapM_ print)
function with another but that doesn't seem to work. Any suggestions?
Edit: Here's an example, as requested
data to print: [["abc","cde","efg"],["hjk","mno","prs"],["stu","wxy","zzz"]]
while using mapM_ (mapM_ print)
it prints like
abc
cde
efg
hjk
mno
prs
stu
wxy
zzz
But I would like it to be printed like this:
abc
cde
efg
hjk
mno
prs
stu
why
zzz
They can be separated by an empty line or some string.
Lets start with types. What you have is [[String]]
and what you want is [[IO ()]]
i.e each String
gets converted to a IO ()
action (to print it). Lets try to achieve this:
strToPrint :: [[String]] -> [[IO ()]]
strToPrint strs = map (map putStrLn) strs
Now we want [[IO ()]]
to flatten to get [IO ()]
where we insert the desired line break print action as well while flattening the list.
flattenActions :: [[IO ()]] -> [IO ()]
flattenActions actions = concat $ intersperse [(putStrLn "")] actions
Now we can execute these [IO ()]
action one by one using sequence_
. It seems we can combine all these functions into one function using functional composition and hence we get
printStrings :: [[String]] -> IO ()
printStrings = sequence_ . flattenActions . strToPrint
And use it like:
main = printStrings [["a","b","c"],["d","e","f"]]
You can then look for making this more generic and refactor it accordingly.