在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的输出。如果您对将无点编程发挥到极致感兴趣,请查看以下答案: