goelakash
goelakash

Reputation: 2519

Reducing this Haskell function

I want to double every second element of a list. Here is the code-

doubleSec n [] = []
doubleSec n (x:xs)
    | n==1 = x*2 : doubleSec 0 xs
    | otherwise = x : doubleSec 1 xs 

doubleSecond xs =
    doubleSec 0 xs

How can I compact this logic in a single function?

Upvotes: 0

Views: 110

Answers (3)

musically_ut
musically_ut

Reputation: 34288

This method will preserve the O(n) running time:

doubleSecond xs =
  [ if isOddStep then 2 * x else x | 
    (isOddStep, x) <- zip (cycle [False, True]) xs ]

An more succinct version by @DavidFletcher:

doubleSecond = zipWith ($) (cycle [id, (2*)])

or:

doubleSecond = zipWith id (cycle [id, (2*)])

as suggested by @Carl.

Upvotes: 2

Simon H
Simon H

Reputation: 21005

How about this

doubleSecond xs = map (\(x,i) -> if odd i then x*2 else x) (zip xs [0..]) 

Upvotes: 3

Hamish
Hamish

Reputation: 1015

You can match a pattern on the list like this

doubleSec :: [Int] -> [Int]
doubleSec [] = []
doubleSec [x] = [x]
doubleSec (x : y : xs) = x : 2* y : doubleSec xs

letting you do specific things to the second element

Upvotes: 8

Related Questions