我刚刚开始使用Haskell并希望做一个小函数,它接受一个整数和一个String来重复String中的每个char,就像整数所暗示的那样。
例如:乘以3"你好"会输出" hhheeelllooo"
我现在的问题是我不知道如何迭代所有的字符。
multiply::Int->String->String
multiply 1 s = s
multiply i s = multiply (i-1) (take 1 s ++ s)
所以我得到的是" hhhello"。所以基本上我需要做一些事情:
mult::Int->String->String
mult 0 s = []
mult 1 s = s
mult i s = "iterate over s, take each char and call a modified version of the multiply method that only takes chars above"
感谢您帮助我
答案 0 :(得分:18)
使用标准库时,这会变得更容易。首先,使用replicate
:
Prelude> replicate 3 'h'
"hhh"
然后,您可以partially apply此功能,map
通过字符串:
Prelude> map (replicate 3) "hello"
["hhh", "eee", "lll", "lll", "ooo"]
最后concat
将字符串列表转换为一个字符串:
Prelude> concat (map (replicate 3) "hello")
"hhheeellllllooo"
concat
和map
的构成可以缩写为concatMap
(这是一个库函数,而不是语言功能)。
Prelude> concatMap (replicate 3) "hello"
"hhheeellllllooo"
所以你的功能变成了
mult n s = concatMap (replicate n) s
为了更加简洁,请在point-free style中将其写为
mult = concatMap . replicate
答案 1 :(得分:5)
有许多方法可以达到与使用其他语言的循环相同的效果,而larsmans使用map
向您展示了一种方法。另一种常见的方法是递归。您已经知道如何处理第一个字符,因此您可以像这样递归列表:
multiply n [] = []
multiply n (x:xs) = replicate n x ++ multiply n xs
larsmans解释了replicate
的工作原理。对于您的作业,也许您不应该使用replicate
之类的库函数,因此您可以用自己的版本替换replicate
的调用。
答案 2 :(得分:4)
另一种基于monadic列表性质的方式。
您想将一个函数应用于列表的每个元素
要执行此操作,只需将列表绑定到该函数,就像这样
# "hello" >>= replicate 3
或者,
# let f = flip (>>=) . replicate
要删除翻转,
# let g = (=<<) . replicate
答案 3 :(得分:1)
您可以使用applicative functor:
import Control.Applicative
multiply n = (<* [1..n])
--- multiply 3 "hello" --> "hhheeellllllooo"