String 学习Haskell:字符串操作问题

String 学习Haskell:字符串操作问题,string,haskell,String,Haskell,我如何用Haskell编写一个函数,它接受格式为a1a2a3的输入字符串并扩展为A1A2A3A3。例如,输入字符串“code”将扩展为“cooddeee”,因此您希望将n字符重复n次 f :: String -> String f x = concatMap g (zip x [1..]) where g (x,y) = replicate y x 我相信有一个更简单的方法 说明:首先,我们获取字符串并将其与列表中的位置配对(从1开始)。这就是zip所做的: Pre

我如何用Haskell编写一个函数,它接受格式为a1a2a3的输入字符串并扩展为A1A2A3A3。例如,输入字符串“code”将扩展为“cooddeee”

,因此您希望将
n
字符重复
n次

f :: String -> String
f x = concatMap g  (zip x [1..])
   where
       g (x,y) = replicate y x
我相信有一个更简单的方法

说明:首先,我们获取字符串并将其与列表中的位置配对(从1开始)。这就是zip所做的:

Prelude> zip "code" [1..]
[('c',1),('o',2),('d',3),('e',4)]
现在函数
g(x,y)
使用replicate函数,它可以复制任意的y次。所以我们复制x,y次

Prelude> g ('z',4)
"zzzz"
如果我们将此函数映射到生成的列表,您将得到以下结果:

Prelude> map g $ zip "code" [1..]
["c","oo","ddd","eeee"]
如果有字符串列表,可以使用
concat
将它们连接在一起
concatMap
将函数
g
应用于每对字母和数字,然后将字符串连接到最终结果中

Prelude> concat $ map g $ zip "code" [1..]
"coodddeeee"
基本上:
concat$map g
->
concat$map g

编辑:现在它可以工作了,也可以在一行中完成,因此:

f x = concatMap (\(a,b)->replicate b a ) $ zip x [1..]
输出:

Prelude> f "lambda"
"laammmbbbbdddddaaaaaa"

可能效率很低:)

屈服

Main> f "code"
"coodddeeee"

Prelude>let l=“code”在concat$[take y$repeat(last$take y l)| y为什么人们讨厌列表理解

Prelude> let f s = concat [ replicate x y | (x,y) <- zip [1..] s]
Prelude> f "code"
"coodddeeee"
Prelude>让f s=concat[复制x y |(x,y)f“代码”
“库德迪”
或者如果你想疯狂地使用扩展

Prelude> :set -XParallelListComp
Prelude> let f s = concat [ replicate x y | x <- [1..] | y <- s]
Prelude> f "code"
"coodddeeee"
Prelude>:set-XParallelListComp

前奏曲>让f s=concat[replicate x y | x请发布您迄今为止为解决此问题而编写的代码。否则人们可能会怀疑这是家庭作业。我向您保证,这不是家庭作业:)我在Haskell的一本书中进行练习,我的大脑刚刚冻结在这一点上。此时我所知道的是,我需要使用++运算符,某种数组manipul你能解释一下这个答案吗,作为一个刚刚开始学习haskell的人,上面的答案对我来说毫无意义。我想用
uncurry.flip replicate
替换
g
。做同样的事情,但是使用标准的haskell库函数。简短版本:
 f=具有复制的concat.zipWith[1..]
sdcvvc应该把他的评论作为一个答案——这对我来说是最清楚的方式。这是:如果在32位机器上有一个长度==maxBound::Int的字符串,那么对该字符串应用此函数的结果将是1+2+3+…+2147483647=2305843 TB——假设每个字符有一个字节,忽略列表开销。Luckily Haskell很懒,所以你可能不需要一次分配所有资源,尽管你仍然需要等待很长时间才能走到最后:-)仅供参考:并置比@更紧密,因此你可以删除一些过度偏执的括号。fn(c:s)=复制nc++f(n+1)sNice!对于像我这样不知道操作符类型的人:“从左到右的Kleisli单子组成:
(>=>)::单子m=>(a->MB)->(b->MC)->(a->MC)
Main> f "code"
"coodddeeee"
Prelude> let l = "code" in concat $ [take y $ repeat (last $ take y l) | y <- [1..length l]]
"coodddeeee"
Prelude> let f s = concat [ replicate x y | (x,y) <- zip [1..] s]
Prelude> f "code"
"coodddeeee"
Prelude> :set -XParallelListComp
Prelude> let f s = concat [ replicate x y | x <- [1..] | y <- s]
Prelude> f "code"
"coodddeeee"