使用foldr编写递归函数

时间:2012-11-14 20:27:24

标签: haskell lambda fold

我是Haskell编程的新手。 练习时,我被要求制作一个如下所示的递归函数:

repeat1 5 [1,2,3] = [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]

repeat1 :: Int -> a -> [a]
repeat1 0 x = []
repeat1 num x = x : repeat1 (num-1) x

我想将它转换为foldr函数,但我不能:(
我已经阅读了http://en.wikibooks.org/wiki/Haskell/List_processing

中的lambda函数和折叠(foldrfoldl)函数

有人可以帮忙吗? 提前致谢

3 个答案:

答案 0 :(得分:3)

foldr用于使用列表的函数。对于生成列表,unfoldr是更自然的选择:

repeat1 :: Int -> a -> [a]
repeat1 n x = unfoldr f n
  where f 0 = Nothing
        f n = Just (x, n-1)

那就是说,在这种情况下,我认为把它写成一个简单的递归更清楚。

答案 1 :(得分:2)

正如hammar指出的那样,foldr不是正确的工具,因为您首先需要一个列表来处理。为什么不简单......

repeat1 n = take n . repeat 

答案 2 :(得分:1)

如果你真的想使用foldr,你可以这样做:

repeat' n x = foldr (\_ acc -> x:acc) [] [1..n]

您基本上使用n创建了一个大小为[1..n]的列表,并且对于该列表的每个元素,您将x附加到累加器(基值[])。最后,您有一个{-1}}的n元素列表。