在Haskell中,如何将字符串相乘?

在Haskell中,如何将字符串相乘?,haskell,Haskell,我正在尝试编写一个函数,它接受一个字符串和一个Int并返回该字符串“Int”次。即: duplicate :: String -> Int -> String 如果我要编写复制“Hello”3,那么输出应该是“HelloHelloHello”很容易: duplicate :: String -> Int -> String duplicate string n = concat $ replicate n string $是。该语言允许以中缀形式(作为运算符)使用具有

我正在尝试编写一个函数,它接受一个
字符串和一个
Int
并返回该字符串“Int”次。即:

duplicate :: String -> Int -> String
如果我要编写
复制“Hello”3
,那么输出应该是
“HelloHelloHello”

很容易:

duplicate :: String -> Int -> String
duplicate string n = concat $ replicate n string
$
是。该语言允许以中缀形式(作为运算符)使用具有非字母数字名称的函数。即,上述函数体与以下表达式完全相同:

($) concat (replicate n string)
concat (replicate n string)
$
所做的只是允许您去掉大括号。这意味着上述表达式只是以下表达式的替代:

($) concat (replicate n string)
concat (replicate n string)

您可以按如下方式使用
replicate
concat

duplicate :: [a] -> Int -> [a]
duplicate = flip $ (concat .) . replicate

-- or as larsmans suggested:

duplicate :: [a] -> Int -> [a]
duplicate = (concat .) . flip replicate

然后将其用作重复的“Hello”3

您可以使用模式匹配

duplicate _ 0 = []
duplicate xs n = xs ++ duplicate xs (n-1)


String
只是
Char
列表的同义词,列表类型是
Monad
。所以

duplicate :: Int -> String -> String
duplicate n str = [1..n] >>= const str
或者,如果你想获得全免积分

duplicate = (. const) . (>>=) . enumFromTo 1

编辑

正如评论中所建议的那样

duplicate n str = [1..n] >> str


再次是初学者的尝试,使用递归


replicate sn=if n太好了,谢谢!我以前见过concat,这是我的第一个猜测。。。但是在这种情况下,$符号做什么?@benharris,
$
操作只是函数应用程序。只有它的优先级最低,并且它是右关联的,而不是左关联的。您应该将
duplicate
的类型签名更改为
[a]->Int->[a]
。这样,您就可以将其用于任何列表。@AaditMShah翻转参数也是有意义的。根本不创建这样一个基本的合成功能也是一个选择。问题是在解释琐碎的东西时,我们想触及多少主题。初学者很容易负担过重。是的。将
n
作为第一个参数是有意义的,因为它允许您编写类似
putStrLn的函数。重复3次
。关于这一点,@benharris,我想你应该读一下。这完全等同于
concat.:flip replicate
,除了内联。我怀疑优化后它们会编译到同一个核心。事实上,对于不了解单子、无点样式等的初学者来说,这是一个很好的答案。简而言之:
(concat.)。flip replicate
。是的,你说得对,我把它和未来的东西混淆了。我将删除注释。这是一个无意义的经典示例。你能一眼告诉我为什么
()
在它们所在的地方吗?他们在做什么?为什么它们是必要的?另一方面,
let(.:)=fmap-fmap-in-concat.:flip-replicate
是使用
fmap-fmap
,或
()
组合具有两个参数的函数的示例。这是一个可以在其他地方重用的习惯用法,而不仅仅是运行
pointfree
@ReinHenrichs的输出。如果您对将无点编程发挥到极致感兴趣,请查看以下答案: