如何在Haskell中正确打印换行符?

时间:2012-01-17 06:17:14

标签: haskell

我正在尝试为每月教程制作Tic Tac Toe游戏并编写此代码以首先制作一个框:

box :: [String]
box = ["0 | 1 | 2",
       "---------",
       "3 | 4 | 5",
       "---------",
       "6 | 7 | 8"]

我在GHCi中得到了这个输出:

["0 | 1 | 2\n","---------\n","3 | 4 | 5\n","---------\n","6 | 7 | 8\n"]

我想得到:

 0 | 1 | 2
 ---------
 3 | 4 | 5
 ---------
 6 | 7 | 8

如何像这样打印网格?

2 个答案:

答案 0 :(得分:28)

尝试类似:

box = unlines $ ["0 | 1 | 2",
                 "---------",
                 "3 | 4 | 5",
                 "---------",
                 "6 | 7 | 8"]

然后使用putStr

输出框
main = putStr box

unlines做的是获取字符串列表并使用换行符将它们连接在一起。它基本上将字符串列表视为行列表并将它们转换为单个字符串。

putStr只是将字符串打印到STDOUT。如果您使用print或GHCi来查看字符串,则换行符将呈现为\n而不是实际换行符。发生这种情况是因为show的{​​{1}}实例用于序列化字符串,就像输入字符串而不是打印它一样。在输出到STDOUT之前,String和GHCi都使用print

如果您处于GHCi提示符并希望查看字符串的实际外观,可以直接使用show

putStr

答案 1 :(得分:8)

另一种方法是

main = mapM_ putStrLn box

mapM :: Monad m => (a -> m b) -> [a] -> m [b]是map的类似物,但对于monadic函数,其强调的表兄mapM_ :: Monad m => (a -> m b) -> [a] -> m ()不收集返回值,因此可以更有效。如果返回值无关紧要,就像putStrLn s一样,mapM_是更好的选择。