Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a filtered list in a new function in haskell

So i'm not too sure how to phrase this properly, but say I wanted to get the sum of all odd numbers in a list, do I have two functions (sumList and getOddNumbers) and combine them into sumOddList or is there a way to put these two together in a single function? If there isnt a better function, how exactly would I combine them into sumOddList?

getOddNumbers :: [Integer] -> [Integer]
getOddNumbers [] = []
getOddNumbers (x:xs)
    |odd x = x:getOddNumbers xs
    |otherwise = getOddNumbers xs

sumList :: [Integer] -> Integer
sumList list = case list of
   [] -> 0
   (x:xs) -> x + (sumList xs)

I also ask mainly because putting two diff functions together is something I struggled with before, when putting a colour and a shape using CodeWorld to output a shape of that colour.

Thank you

(Note: I've been using Haskell for just over 5 weeks now and I'm a total noob clearly)

like image 471
CB010101 Avatar asked Jan 01 '23 22:01

CB010101


1 Answers

Passing output as input to (another) function

Well what you basically want to do is use the output of the getOddNumbers as input for the sumList function, so we can define a sumOddList function as:

sumOddList :: [Integer] -> Integer
sumOddList l = sumList (getOddNumbers l)

Here l is the list we want to process, and the result is thus a function application on the result of getOddNumbers l (with sumList the function).

Chaining functions: the (.) function

The above pattern is quite common: frequently we want to pass data first through a function g, and the result through a function f. Haskell has the (.) :: (b -> c) -> (a -> b) -> a -> c function to "chain" functions. We can thus chain sumList and getOddNumbers together like:

sumOddList :: [Integer] -> Integer
sumOddList = (.) sumList getOddNumbers

Notice that we no longer use an l parameter here. sumOddList is here defined as a "pipeline" where data is first passed to the getOddNumbers, and then is "post-processed" by the sumList function.

The (.) function can also be used as an infix operator:

sumOddList :: [Integer] -> Integer
sumOddList = sumList . getOddNumbers
like image 163
Willem Van Onsem Avatar answered Jan 05 '23 01:01

Willem Van Onsem