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

Haskell将[[[Char]]]打印到IO,haskell,io,system.printing,Haskell,Io,System.printing,您好,我在使用IO打印[[[Char]]]时遇到了一个小问题 我有一个[[[Char]]]列表-换句话说[[String]] 我想把它们打印出来 FirstStringOfFirstListOfStrings SecondStringOfFirstListOfStrings . . . LastStringOffFirstListofStrings (some gap anything empty line "----" string anything) FirstStringOfSeconds

您好,我在使用IO打印[[[Char]]]时遇到了一个小问题

我有一个[[[Char]]]列表-换句话说[[String]]

我想把它们打印出来

FirstStringOfFirstListOfStrings
SecondStringOfFirstListOfStrings
.
.
.
LastStringOffFirstListofStrings
(some gap anything empty line "----" string anything)
FirstStringOfSecondsListOfStrings
换句话说,我不希望[String]被一行一行地打印出来,或者至少有一行被填空---例如

mapM_ (mapM_ print) 
我的想法是用另一个函数组合mapM_uu打印函数,但这似乎不起作用。有什么建议吗

编辑:这里有一个例子,根据要求

要打印的数据:[[abc、cde、efg]、[hjk、mno、prs]、[stu、wxy、zzz]]

使用mapM_uuM_uu打印时,它会像

abc
cde
efg
hjk
mno
prs
stu
wxy
zzz
但我希望它是这样印刷的:

abc
cde
efg

hjk
mno
prs

stu
why
zzz

它们可以用空行或字符串分隔。

在您的示例中,任何分隔符“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

在您的示例中,任何分隔符“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

让我们从类型开始。您拥有的是[[String]],您想要的是[[IO]],即每个字符串都转换为IO操作以打印它。让我们试着做到这一点:

strToPrint :: [[String]] -> [[IO ()]]
strToPrint strs = map (map putStrLn) strs                
现在,我们希望[[IO]]展平以获得[IO],在展平列表的同时,插入所需的换行打印操作

flattenActions :: [[IO ()]] -> [IO ()]
flattenActions actions = concat $ intersperse [(putStrLn "")]  actions
现在我们可以使用sequence\ux逐个执行这些[IO]操作。似乎我们可以使用函数组合将所有这些函数组合成一个函数,从而得到

printStrings :: [[String]] -> IO ()
printStrings  = sequence_ . flattenActions . strToPrint
然后像这样使用它:

main = printStrings [["a","b","c"],["d","e","f"]]

然后,您可以寻求使它更通用,并相应地重构它。

让我们从类型开始。您拥有的是[[String]],您想要的是[[IO]],即每个字符串都转换为IO操作以打印它。让我们试着做到这一点:

strToPrint :: [[String]] -> [[IO ()]]
strToPrint strs = map (map putStrLn) strs                
现在,我们希望[[IO]]展平以获得[IO],在展平列表的同时,插入所需的换行打印操作

flattenActions :: [[IO ()]] -> [IO ()]
flattenActions actions = concat $ intersperse [(putStrLn "")]  actions
现在我们可以使用sequence\ux逐个执行这些[IO]操作。似乎我们可以使用函数组合将所有这些函数组合成一个函数,从而得到

printStrings :: [[String]] -> IO ()
printStrings  = sequence_ . flattenActions . strToPrint
然后像这样使用它:

main = printStrings [["a","b","c"],["d","e","f"]]

然后,您可以寻找使其更通用的方法,并相应地对其进行重构。

请记住,mapM_u使用一个返回一元操作作为其参数的函数。这一行动可能是错误的 使用正常的一元运算合成

因此,在您的代码示例中,您有:

printStrings :: [[String]] -> IO ()
printStrings = mapM_ (mapM_ putStrLn)
鉴于您希望:

printStrings :: [[String]] -> IO ()
printStrings = mapM_ (\xs -> (mapM_ putStrLn) xs >> putStrLn ""))
因此,我们要做的是用一个函数替换内部mapM_uuuputstrln:
\xs->mapM_uuuPutstrlnxs>>也打印出分隔符的putStrLn。

请记住,mapM_uuuu使用一个返回一元操作作为其参数的函数。这一行动可能是错误的 使用正常的一元运算合成

因此,在您的代码示例中,您有:

printStrings :: [[String]] -> IO ()
printStrings = mapM_ (mapM_ putStrLn)
鉴于您希望:

printStrings :: [[String]] -> IO ()
printStrings = mapM_ (\xs -> (mapM_ putStrLn) xs >> putStrLn ""))
因此,我们要做的是用一个函数替换内部mapM_uuuputstrln:
\xs->mapM_uuPutstrnXS>>也打印出分隔符的Putstrn。

您可以通过显示示例输入和输出来帮助我们。在调用IO之前,还应该考虑使用纯函数来定义要输出的最终字符串。Board是大型非确定性算法的结果,使其变得纯粹是相当困难的,我认为有办法做到这一点,但monad类型限制了我,您可以通过显示示例输入和输出来帮助我们。在调用IO之前,您还应该考虑使用纯函数来定义要输出的最终字符串。正如您所要求的,我把代码的一个例子很好地说明[[Str] ]板是一个大的非确定性算法的结果,使它变得纯得很难。我认为有办法做到这一点,但Munad类型限制了我的困难,因为我是一个挑剔者。我要指出的是。穿插==插入,但我认为后者更有效率。因为我是个挑剔的人,我要指出。插入,插入,但我认为后者更有效率。