Haskell process list from right to left, keeping order of origin

You need to increase every second element, starting from the right one in the Haskell list, but keep the order of origin (for example, it reversedoes not apply). For example:

 f [1, 2, 3] --  [1, 3, 3]

 f [1, 2, 3, 4] -- [2, 2, 4, 4]

I tried something like the following:

fc ([]) = []
fc (x:[]) = [x]
fc (x:[y]) = [x+1,y]
fc( x:xs ) = fc [x] : ( fc xs ) -- this line is wrong

ps Obviously, I could change (but prefer to understand the original task) in the list twice and apply something like:

helper (x:y:tail) = [x, y+1] ++ tail
fc x = reverse (helper (reverse x) )
+4
source share
4 answers

This can be done effectively using the left fold:

inc :: Num a => [a] -> [a]
inc xs = foldl go (\_ _ acc -> acc) xs id (+ 1) []
    where go run x f g acc = run g f (f x: acc)

, , , cons (:) operator; , ( , ).

\> inc [1, 2, 3]
[1,3,3]
\> inc [1, 2, 3, 4]
[2,2,4,4]

, id (+ 1).

+2

Haskell . , :

f1 = reverse . zipWith (+) (cycle [0,1]) . reverse

, , , , , , :

f2 = snd . g
  where
  g []     = (False, [])
  g (x:xs) = let (addOne, xs') = g xs
                 x' = if addOne then x + 1 else x
             in (not addOne, x':xs')

, , , . , :

import Data.List (mapAccumR)
f2' = snd . mapAccumR g False
  where
  g addOne x = (not addOne, if addOne then x + 1 else x)
+4

, , , , , , , . , 3 1. - :

f xs = zipWith (+) (cycle sol) xs
 where sol = map fromEnum [even len, odd len] 
       len = length xs

( ), " ". ( ).

f2 xs = let (isEven, result) = go isEven xs in result
 where
  go _ []     = (True,     [])
  go e (x:xs) = let (ne,rest) = go (not e) xs
                in (not ne, x+fromEnum e : rest)
+4

I like Thomas's decision. However, I think it’s quite simple here foldr.

process = snd . foldr (\x (b,xs) -> (not b, x + fromEnum b:xs)) (False,[])
0
source

Source: https://habr.com/ru/post/1609182/


All Articles