[英]Haskell printing [[[Char]]] to IO
嗨,我在使用IO打印[[[Char]]]
小问题。
我有一个[[[Char]]]
列表-换句话说[[String]]
我想像打印
FirstStringOfFirstListOfStrings
SecondStringOfFirstListOfStrings
.
.
.
LastStringOffFirstListofStrings
(some gap anything empty line "----" string anything)
FirstStringOfSecondsListOfStrings
换句话说,我不希望将[String]
一个接一个地打印(例如,至少要换行或用------
填充一行)
mapM_ (mapM_ print)
我的想法是将(mapM_ print)
函数与另一个函数组合在一起,但这似乎不起作用。 有什么建议么?
编辑:这是一个示例,根据要求
要打印的数据: [["abc","cde","efg"],["hjk","mno","prs"],["stu","wxy","zzz"]]
在使用mapM_ (mapM_ print)
其打印效果类似于
abc
cde
efg
hjk
mno
prs
stu
wxy
zzz
但是我希望这样打印:
abc
cde
efg
hjk
mno
prs
stu
why
zzz
它们可以用空行或某些字符串分隔。
让我们从类型开始。 您所拥有的是[[String]]
而您想要的是[[IO ()]]
即每个String
被转换为IO ()
操作(以打印它)。 让我们尝试实现这一点:
strToPrint :: [[String]] -> [[IO ()]]
strToPrint strs = map (map putStrLn) strs
现在,我们希望将[[IO ()]]
展平以得到[IO ()]
,在我们展平列表的同时也插入所需的换行打印动作。
flattenActions :: [[IO ()]] -> [IO ()]
flattenActions actions = concat $ intersperse [(putStrLn "")] actions
现在我们可以使用sequence_
一一执行这些[IO ()]
动作。 似乎我们可以使用功能组合将所有这些功能组合为一个功能,因此我们得到
printStrings :: [[String]] -> IO ()
printStrings = sequence_ . flattenActions . strToPrint
并像这样使用它:
main = printStrings [["a","b","c"],["d","e","f"]]
然后,您可以寻找使它更通用的名称,并相应地对其进行重构。
在您的示例代码中,任何分隔符“ sep”为:
import Data.List (intercalate)
let x = [["abc","cde","efg"],["hjk","mno","prs"],["stu","wxy","zzz"]]
p sep = putStr . unlines . intercalate sep
main = do
p "" x
p "---" x
请记住,mapM_接受一个返回单调动作的函数作为其参数。 可以使用正常的单声道操作来构成该动作。
因此,在您的代码示例中,您可以:
printStrings :: [[String]] -> IO ()
printStrings = mapM_ (mapM_ putStrLn)
而您希望拥有:
printStrings :: [[String]] -> IO ()
printStrings = mapM_ (\xs -> (mapM_ putStrLn) xs >> putStrLn ""))
因此,我们要做的是将内部mapM_ putStrLn
替换为一个函数: \\xs -> mapM_ (putStrLn xs >> putStrLn "")
,该函数也会打印出分隔符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.