Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: Double every 2nd element in list

Tags:

haskell

I just started using Haskell and wanted to write a function that, given a list, returns a list in which every 2nd element has been doubled.

So far I've come up with this:

double_2nd :: [Int] -> [Int]
double_2nd [] = []
double_2nd (x:xs) = x : (2 * head xs) : double_2nd (tail xs)

Which works but I was wondering how you guys would write that function. Is there a more common/better way or does this look about right?

like image 763
user2036087 Avatar asked Jun 29 '13 18:06

user2036087


3 Answers

That's not bad, modulo the fixes suggested. Once you get more familiar with the base library you'll likely avoid explicit recursion in favor of some higher level functions, for example, you could create a list of functions where every other one is *2 and apply (zip) that list of functions to your list of numbers:

double = zipWith ($) (cycle [id,(*2)])
like image 146
Thomas M. DuBuisson Avatar answered Oct 30 '22 10:10

Thomas M. DuBuisson


You can avoid "empty list" exceptions with some smart pattern matching.

double2nd (x:y:xs) = x : 2 * y : double2nd xs
double2nd a = a

this is simply syntax sugar for the following

double2nd xss = case xss of
    x:y:xs -> x : 2 * y : double2nd xs
    a -> a

the pattern matching is done in order, so xs will be matched against the pattern x:y:xs first. Then if that fails, the catch-all pattern a will succeed.

like image 22
cdk Avatar answered Oct 30 '22 10:10

cdk


A little bit of necromancy, but I think that this method worked out very well for me and want to share:

double2nd n = zipWith (*) n (cycle [1,2])

zipWith takes a function and then applies that function across matching items in two lists (first item to first item, second item to second item, etc). The function is multiplication, and the zipped list is an endless cycle of 1s and 2s. zipWith (and all the zip variants) stops at the end of the shorter list.

like image 10
steegness Avatar answered Oct 30 '22 10:10

steegness