0

i have a list

[1,1,1,1,1]

and i am trying to write function which will return list

[2,3,4,5,6]

i want to use function map like this

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

which will return

[2,2,2,2,2]

after that i want to call map function on last four elements of returned list so after i get [2,2,2,2,2] i want to use map on last four [2,2,2,2] that will return [3,3,3,3] and replace last four elements from first map call so i get [2,3,3,3,3] etc..

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]

returned:

[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]

i need to return only last list... btw this is only Simplified version, originaly i have list of lists ... i just cant figure how to call function how i described.. thanks.

3
  • Should all immediate steps be returned? Or only the last list, [2,3,4,5,6] Commented Mar 18, 2013 at 16:47
  • And how can we help you? Commented Mar 18, 2013 at 16:47
  • only last list [2,3,4,5,6] Commented Mar 18, 2013 at 17:13

6 Answers 6

8

I think you want something like

mapTails f [] = []
mapTails f (x:xs) = f x : mapTails f (map f xs)
Sign up to request clarification or add additional context in comments.

Comments

4

IMO the most elegant way would be

zipWith($) $ iterate((+1).) id

2 Comments

Fantastic! I think it should be zipWith($) $ tail $ iterate((+1).) id.
I like this solution most. The others are either not generic enough or not very elegant. +1. Although I would use more haskelly syntax and no ($): zipWith ($) (iterate (succ .) succ) (replicate 5 1).
3

scanl almost does what you want:

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

You could drop the first item, which is just the initial state value we're passing in:

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

1 Comment

I don't think OP is seeking this function, though it yields the right answer for the case (+1). For other input function, e.g. (+2), it won't work.
1

You can accomplish what you're looking for using a recursive function, instead:

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]

See http://codepad.org/wBwynlGt

Comments

0

Would something like this do what you want?

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

The zip basically pairs each element in the list with what you want to add to it, and the map function then adds each element in the list to that value to get the result you want.

Comments

0

Your algorithm version O(n2) time:

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

Faster version O(n) time:

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

pf :: [Int] -> Int -> [Int]
pf [] _ = []
pf (x:xs) n = (x+n):(pf xs (n+1))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.