Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the gcd of a list

Tags:

haskell

I am new to Haskell, actually I just started, and I would like to get a small hint to the question I am about to ask.

I am currently trying to get the GCD of a given list. For example, having the list [3, 6, 9] it will return 3.

For the moment, I tought of the following aproach, am I going in a good direction?

let getGCD l = map (\x y -> gcd x y) l
like image 388
Timothy Walker Avatar asked Mar 30 '16 19:03

Timothy Walker


1 Answers

Not quite, you don't want map but rather a fold. map will let you transform every element in the list uniformly, so you give it a local transformation a -> b and it gives you a global transformation ([a] -> [b]). This isn't really what you want.

As a quick primer on folds, there's a whole family of them which all let us express computations which we build up by repeatedly applying a function to an initial value, the next element and the list, and then repeating with the result of that application as the new initial value. So foldl' (+) 0 [1, 2, 3, 4] would so something like

 foldl' (+) 0 [1, 2, 3, 4] ==>
 foldl' (+) 1 [2, 3, 4] ==>
 foldl' (+) 3 [3, 4] ==>
 foldl' (+) 6 [4] ==>
 foldl' (+) 10 [] ==> -- For empty lists we just return the seed given
 10

Can you see how to slot your problem into this framework?

More hints

You want to take a list and compute a result which depends on every element of the list, something like

gcdAll :: [Int] -> Int
gcdAll l = foldl' step initial l

is closer to what you want where step takes the current gcd of the list you've processed so far and the next element of the list and returns the next value and initial is the value to start with (and what is returned if l is empty. Since there isn't really a sane value, I'd instead split this into

gcdAll :: [Int] -> Maybe Int
gcdAll [] = Nothing
gcdAll (h : rest) = Just $ foldl' step h rest

so that you correctly signal the possibility of failure, after all, what's the gcd of nothing?

Note that foldl' is imported from Data.List.

like image 78
Daniel Gratzer Avatar answered Sep 20 '22 22:09

Daniel Gratzer