Intermediate value in simple Haskell function

  • A+
Category:Languages

I need a function to double every other number in a list. This does the trick:

doubleEveryOther :: [Integer] -> [Integer] doubleEveryOther []         = [] doubleEveryOther (x:[])     = [x] doubleEveryOther (x:(y:zs)) = x : 2 * y : doubleEveryOther zs 

However, the catch is that I need to double every other number starting from the right - so if the length of the list is even, the first one will be doubled, etc.

I understand that in Haskell it's tricky to operate on lists backwards, so my plan was to reverse the list, apply my function, then output the reverse again. I have a reverseList function:

reverseList :: [Integer] -> [Integer] reverseList  [] = [] reverseList  xs = last xs : reverseList (init xs)  

But I'm not quite sure how to implant it inside my original function. I got to something like this:

doubleEveryOther :: [Integer] -> [Integer] doubleEveryOther []         = [] doubleEveryOther (x:[])     = [x] doubleEveryOther (x:(y:zs)) =  | rev_list = reverseList (x:(y:zs))  |  rev_list = [2 * x, y] ++ doubleEveryOther zs 

I'm not exactly sure of the syntax of a function that includes intermediate values like this.

In case it's relevant, this is for Exercise 2 in CIS 194 HW 1.

 


This is a very simple combination of the two functions you've already created:

doubleEveryOtherFromRight = reverseList . doubleEveryOther . reverseList 

Note that your reverseList is actually already defined in the standard Prelude as reverse. so you didn't need to define it yourself.

I'm aware that the above solution isn't very efficient, because both uses of reverse need to pass through the entire list. I'll leave it to others to suggest more efficient versions, but hopefully this illustrates the power of function composition to build more complex computations out of simpler ones.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: