在Haskell中将字符串打印为模式

在Haskell中将字符串打印为模式,haskell,Haskell,我来自OO背景,对Haskell非常陌生。 要打印类似以下内容的图案: 1 2 3 4 5 1 2 3 4 1 2 3 1 2 1 我列了一张单子 let xs = ["1 2 3 4 5\n" ,"1 2 3 4\n" ,"1 2 3\n" ,"1 2\n" ,"1\n"] 但是我得到的结果是 ["1 2 3 4 5\n","1 2 3 4\n","1 2 3\n","1 2\n","1\n"] 如何获得所需的输出?

我来自OO背景,对Haskell非常陌生。 要打印类似以下内容的图案:

1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
我列了一张单子

let xs = ["1 2 3 4 5\n"
         ,"1 2 3 4\n"
         ,"1 2 3\n"
         ,"1 2\n"
         ,"1\n"]
但是我得到的结果是

["1 2 3 4 5\n","1 2 3 4\n","1 2 3\n","1 2\n","1\n"]
如何获得所需的输出?

简单的回答是

mapM_ putStr xs
基本上,这会对列表中的每个成员执行
putStr
。也就是说,它接受
xs
中的每个字符串并将其打印出来


顺便说一句,您在
show xs
中看到的输出是一个有效的Haskell表达式-您可以将其传递给
read
函数以重新创建
xs

您可以使用unlines函数将字符串列表转换为单个字符串,并使用“\n”作为终止符。它就像一个.join('\n')

屈服

"1\n2\n3\n"

然后,您可以使用putStrLn(仅打印字符串)或打印(打印所有对象)

进行详细说明,您可以这样同时执行这两项操作:

ghci> putStrLn $ unlines $ ["1 2 3 4 5"
                           ,"1 2 3 4"
                           ,"1 2 3"
                           ,"1 2"
                           ,"1"]
triangle :: Int -> String
triangle n = unlines . map (unwords . map show) $ [[1 .. k] | k <- [n, n-1 .. 1]]

Prelude> putStr $ triangle 7
1 2 3 4 5 6 7
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1

import Data.List (intersperse)

triangleOf :: [Char] -> Int -> String
triangleOf chars n = unlines . map (intersperse ' ') $ [take k chars | k <- [n, n-1 .. 1]]

Prelude Data.List> putStr $ triangleOf "Haskell" 7
H a s k e l l
H a s k e l
H a s k e
H a s k
H a s
H a
H
$的优先级非常低,并且是右关联的,因此其行为方式与

ghci> (putStrLn (unlines ["1 2 3 4 5"
         ,"1 2 3 4"
         ,"1 2 3"
         ,"1 2"
         ,"1"]))

要添加更多内置商品,请执行以下操作:

您不需要手动为这样的图案生成线条:

ghci> putStrLn $ unlines $ ["1 2 3 4 5"
                           ,"1 2 3 4"
                           ,"1 2 3"
                           ,"1 2"
                           ,"1"]
triangle :: Int -> String
triangle n = unlines . map (unwords . map show) $ [[1 .. k] | k <- [n, n-1 .. 1]]

Prelude> putStr $ triangle 7
1 2 3 4 5 6 7
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1

import Data.List (intersperse)

triangleOf :: [Char] -> Int -> String
triangleOf chars n = unlines . map (intersperse ' ') $ [take k chars | k <- [n, n-1 .. 1]]

Prelude Data.List> putStr $ triangleOf "Haskell" 7
H a s k e l l
H a s k e l
H a s k e
H a s k
H a s
H a
H
triangle::Int->String
三角形n=未线。地图(unwords.map show)$[[1..k]| k putStr$三角形7
1 2 3 4 5 6 7
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1.
导入数据列表(散布)
triangleOf::[Char]->Int->String
triangleOf chars n=unlines.map(点缀“”)$[take k chars | k putStr$triangleOf“Haskell”7
H a s k e l
H a s k e l
H a s k e
H a s k
哈斯
哈
H

例如,您可以使用
takeWhile(not.null)(tails chars)
获得其他模式,有很多变体。

在一个表达式中看到两个
$
是非常罕见的:通常这将被写入
putStrLn.unlines$[…]
为什么不作为
putStrLn$unlines[…]
?命令式编程人员可能会发现自己可以轻松地使用
表单
,这相当于
mapM
,但需要交换输入。例如
表单[1..10]打印
import Data.List

putStr $ unlines $ map (unwords.(map show)) $ reverse $ inits [1..5]