1

我刚从 Haskell 开始,想做一个小函数,它需要一个整数和一个字符串来重复字符串中的每个字符,就像整数所暗示的那样频繁。

例如:乘以 3 "hello" 将输出 "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"

谢谢你帮助我

4

4 回答 4

18

当您使用标准库时,这会变得更容易。首先,重复一个项目是通过replicate

Prelude> replicate 3 'h'
"hhh"

然后,您可以部分地应用此函数并将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

为了更加简洁,请以无点样式将其写为

mult = concatMap . replicate
于 2013-04-30T09:38:55.770 回答
5

有很多方法可以实现与使用其他语言的循环相同的效果,而 larsmans 向您展示了一种方法,使用map. 另一种常见的方法是递归。您已经知道如何处理第一个字符,因此您可以像这样递归列表:

multiply n [] = []
multiply n (x:xs) = replicate n x ++ multiply n xs

larsmans 解释了它是如何replicate工作的。对于您的家庭作业,也许您不应该使用类似的库函数replicate,因此您可以将调用替换为replicate您自己的版本。

于 2013-04-30T09:42:42.643 回答
4

另一种基于单子列表性质的方法。
您想对列表的每个元素应用一个函数。
为此,只需将列表绑定到函数,就像这样

# "hello" >>= replicate 3

或者,

# let f = flip (>>=) . replicate 

要删除翻转,

# let g = (=<<) . replicate
于 2013-04-30T15:39:20.773 回答
1

您可以为此使用应用函子:

import Control.Applicative

multiply n = (<* [1..n])

--- multiply 3 "hello" --> "hhheeellllllooo"
于 2013-05-01T12:39:37.063 回答