在Haskell中保存值的任何方法?

时间:2015-11-27 20:59:44

标签: haskell

我正在写一个非常简单的复制函数,它接受一个数字列表并返回一个列表,每个数字都是重复的。接受值和元素的复制函数对我来说更简单,因为它不需要保存状态。

但是在Haskell,我到目前为止得到了这个:

> replicate' [] = []
> replicate' (x:xs)
>           | x == 1    = x: replicate' xs
>           | otherwise = x: replicate'(x-1:xs)

这显然是错误的,因为对于replicate' [2,2],它会打印[2,1,2,1]而不是[2,2,2,2]

我知道我必须将x保存到其他变量并递减它但我不相信我知道它的语法。

哎呀,人们对这个问题感到有些困惑。

例如,来电replicate' [2,3,1]应该返回[2,2,3,3,3,1],而不只是[2,2,3,3,1,1],就像我认为你们在想的那样

3 个答案:

答案 0 :(得分:5)

  

我知道我必须将x保存到其他变量

不,你不是。这句话表明你有一些误解。我建议你考虑为什么你认为这是真的,并解决这个问题。

至于你的问题,你有一个良好的开端,向你展示递归,基本情况和基本语法。干得好。您提供的代码是:

replicate' [] = []
replicate' (x:xs)
          | x == 1    = x: replicate' xs
          | otherwise = x: replicate'(x-1:xs)

基本情况很好,但为什么要从x中减去一个呢?为什么它(再次)出现在复制调用中?只要想想你想要的操作,就不需要对元素进行任何算术 - 你想构建一个重复每个元素的列表,语法就像newelement : rest - 我们可以将:读作& #34;缺点&#34 ;.所以你的第二个案例应该是:

replicate' (x:xs) = x : x : replicate' xs

再次编辑,因为您已经澄清了元素是指示它们必须出现多少次的数字。好吧,显而易见的解决方案是使用replicate(from base)作为replicate'的一部分:

replicate' [] = []
replicate' (x:xs) = replicate x x ++ replicate' xs

在上面我们复制每个元素的次数等于元素的值,然后通过++将该列表连接到递归调用。更简单的版本是:

replicate' = concatMap (\x -> replicate x x)

例如:

Prelude> concatMap (\x -> replicate x x) [1..3]
[1,2,2,3,3,3]

答案 1 :(得分:3)

replicate' [] = []
replicate' (x:xs) = x:x:replicate' xs

您可以立即添加两个项目。

*Main> replicate' [1,2,3]
[1,1,2,2,3,3]

<强> UPD:

duplicate::Int->Int->[Int]
duplicate 0 x = []
duplicate n x = x:duplicate (n-1) x

replicate' [] = []
replicate' (x:xs) = duplicate x x ++(replicate' xs)

答案 2 :(得分:1)

根据你的逻辑(但是很差的例子)我猜你想要重复每个元素的次数([2,3] -> [2,2,3,3,3])。

您可以将repeat'函数编写为repeat' n = take n $ repeat n并在复制函数中使用

replicate' :: [Int] -> [Int]
replicate' [] = []
replicate' (x:xs) = repeat' x ++ replicate' xs

更新:

你可以写一个重复的&#39;递归函数,你需要使用辅助函数来携带额外的计数信息。这样的事情应该有效

 rep :: Int -> [Int]
 rep x = rep' x x
   where rep' x 0 = []
         rep' x n = x: rep' x (n-1)

此处不是保存您作为递减参数传递的状态(计数),而是类似于循环计数。