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

Rog*_*ews 13 haskell

我试图为月度教程制作Tic Tac Toe游戏并编写此代码以首先制作一个盒子:

box :: [String]
box = ["0 | 1 | 2",
       "---------",
       "3 | 4 | 5",
       "---------",
       "6 | 7 | 8"]
Run Code Online (Sandbox Code Playgroud)

我在GHCi中获得此输出:

["0 | 1 | 2\n","---------\n","3 | 4 | 5\n","---------\n","6 | 7 | 8\n"]
Run Code Online (Sandbox Code Playgroud)

我想得到:

 0 | 1 | 2
 ---------
 3 | 4 | 5
 ---------
 6 | 7 | 8
Run Code Online (Sandbox Code Playgroud)

我该如何打印这样的网格?

Tik*_*vis 28

尝试类似的东西:

box = unlines $ ["0 | 1 | 2",
                 "---------",
                 "3 | 4 | 5",
                 "---------",
                 "6 | 7 | 8"]
Run Code Online (Sandbox Code Playgroud)

然后输出框使用putStr:

main = putStr box
Run Code Online (Sandbox Code Playgroud)

什么unlines是字符串列表并使用换行符将它们连接在一起.它基本上将字符串列表视为行列表并将它们转换为单个字符串.

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

如果您处于GHCi提示符并想要查看字符串的实际外观,可以putStr直接使用:

*Main> putStr box
0 | 1 | 2
---------
3 | 4 | 5
---------
6 | 7 | 8
*Main>
Run Code Online (Sandbox Code Playgroud)


Kar*_*elė 8

另一种方法是

main = mapM_ putStrLn box
Run Code Online (Sandbox Code Playgroud)

mapM :: Monad m => (a -> m b) -> [a] -> m [b]是地图的类比,但对于monadic函数,其强调的表兄,mapM_ :: Monad m => (a -> m b) -> [a] -> m ()不收集返回值,因此可以更有效.如果返回值无趣,那么putStrLn s,mapM_是更好的选择.