【问题标题】:haskell repeat all chars in a stringhaskell 重复字符串中的所有字符
【发布时间】:2013-04-24 03:58:40
【问题描述】:

我刚开始使用 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"

谢谢你帮助我

【问题讨论】:

  • 这是家庭作业吗?
  • 不,第一个是作业,乘以第一个字母 - 但我得到了这个并想做更多的事情。基本上我只是不明白如何循环。我的尝试是从列表中删除我访问过的每个字母,就像在 java 或 c++ 中一样,但我想这在这里行不通
  • 附带说明,我们不倾向于在 Haskell 中进行迭代;函数式编程适用于递归解决方案,例如下面的 mhwombat。

标签: loops haskell recursion char


【解决方案1】:

当您使用标准库时,这会变得更容易。首先,使用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"

concatmap的组合可以简写为concatMap(这是库函数,不是语言特性)。

Prelude> concatMap (replicate 3) "hello"
"hhheeellllllooo"

所以你的函数变成了

mult n s = concatMap (replicate n) s

为了更加简洁,请将其写在point-free style

mult = concatMap . replicate

【讨论】:

  • 非常感谢,这对我来说似乎比做我想做的事情更容易
  • 你也可以只使用(>>=)作为列表单子(或多或少concatMap):"hello" >>= replicate 3产生"hhheeellllllooo"
【解决方案2】:

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

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

larsmans 解释了replicate 的工作原理。对于你的家庭作业,也许你不应该使用像replicate 这样的库函数,所以你可以用你自己的版本替换对replicate 的调用。

【讨论】:

    【解决方案3】:

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

    # "hello" >>= replicate 3
    

    或者,

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

    要移除翻转,

    # let g = (=<<) . replicate
    

    【讨论】:

      【解决方案4】:

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

      import Control.Applicative
      
      multiply n = (<* [1..n])
      
      --- multiply 3 "hello" --> "hhheeellllllooo"
      

      【讨论】:

        猜你喜欢
        • 2021-10-18
        • 2021-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多