Here's how I would do it:
mapToEverySecond f xs = foldr go (`seq` []) xs False where go x cont !mapThisTime = (if mapThisTime then fx else x) : cont (not mapThisTime)
But if I were writing library code, I would probably wrap this in a build form.
Edit
Yes, this can also be done using mapAccumL or traverse .
import Control.Applicative import Control.Monad.Trans.State.Strict import Data.Traversable (Traversable (traverse), mapAccumL) mapToEverySecond :: Traversable t => (a -> a) -> ta -> ta -- Either mapToEverySecond f = snd . flip mapAccumL False (\mapThisTime x -> if mapThisTime then (False, fx) else (True, x)) -- or mapToEverySecond f xs = evalState (traverse step xs) False where step x = do mapThisTime <- get put (not mapThisTime) if mapThisTime then return (fx) else return x
Or you can do it with scanl , which I will leave to you for clarification.
source share