繁体   English   中英

Haskell将[[[Char]]]打印​​到IO

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM