0

我有一个清单

[1,1,1,1,1]

我正在尝试编写将返回列表的函数

[2,3,4,5,6]

我想像这样使用功能图

map (+1) [1,1,1,1,1]

这将返回

[2,2,2,2,2]

之后我想在返回列表的最后四个元素上调用 map 函数,所以在我得到 [2,2,2,2,2] 之后我想在最后四个 [2,2,2,2] 上使用 map 将返回[3,3,3,3] 并替换第一次地图调用的最后四个元素,所以我得到 [2,3,3,3,3] 等。

map (+1)[1,1,1,1,1] 
map (+1)  [2,2,2,2] 
map (+1)    [3,3,3] 
map (+1)      [4,4] 
map (+1)        [5]

回来:

[2,2,2,2,2]
[2,3,3,3,3] 
[2,3,4,4,4]
[2,3,4,5,5]
[2,3,4,5,6]

我只需要返回最后一个列表...顺便说一句,这只是简化版本,原来我有列表列表...我只是不知道如何调用我描述的函数..谢谢。

4

6 回答 6

8

我想你想要类似的东西

mapTails f [] = []
mapTails f (x:xs) = f x : mapTails f (map f xs)
于 2013-03-18T16:55:49.810 回答
4

IMO 最优雅的方式是

zipWith($) $ iterate((+1).) id
于 2013-03-18T17:26:10.760 回答
3

scanl 几乎可以满足您的要求:

Prelude> scanl (+) 1 [1,1,1,1,1]
[1,2,3,4,5,6]

您可以删除第一项,它只是我们传入的初始状态值:

Prelude> tail $ scanl (+) 1 [1,1,1,1,1]
[2,3,4,5,6]
于 2013-03-18T16:54:27.987 回答
1

您可以使用递归函数来完成您正在寻找的东西,而不是:

myFn :: Num a => [a] -> [a]
myFn []     = []
myFn (x:xs) = x + 1 : (myFn $ map (+1) xs)

main = print $ myFn [1,1,1,1,1]  -- Prints [2,3,4,5,6]

http://codepad.org/wBwynlGt

于 2013-03-18T16:56:42.217 回答
0

您的算法版本 O(n 2 ) 时间:

plusSlow :: [Int] -> [Int]
plusSlow [] = []
plusSlow (x:xs) = (head mapped):(plusSlow $ tail mapped)
                 where mapped = map (+1) (x:xs)

更快的版本 O(n) 时间:

plusFast :: [Int] -> [Int]
plusFast x = pf x 1

pf :: [Int] -> Int -> [Int]
pf [] _ = []
pf (x:xs) n = (x+n):(pf xs (n+1))
于 2013-03-18T16:55:01.957 回答
0

这样的事情会做你想要的吗?

startList = [1,1,1,1] -- orwhatever you want it to be 
map (\(x,i) -> x + i) $ zip startList [1..]

zip基本上将列表中的每个元素与您要添加到其中的内容配对,然后 map 函数将列表中的每个元素添加到该值以获得您想要的结果 。

于 2013-03-18T16:50:00.923 回答