timothyylim
timothyylim

Reputation: 1527

Iterate through a list and populate a resulting list [Haskell]

I would like to do the following:

let a = [1,2,3,4]
let res = []

for (i = 0; i < a.length; i++) {
  if (someFilterFunction(x) == true) {
    res.push(a[i])
  }
}

return res 

In Haskell, I assumed it would use takewhile but I need the function to not skip when the condition is not met.

Upvotes: 0

Views: 131

Answers (1)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

We would like to do the following in Haskell: Write a function that takes a list as input, checks each element if it matches some test (aka predicate, filter function), include the element in a result list if the test succeeds.

So we want a function that accepts a list of some type of values (let's call them Ints) and returns a list:

timothyylim :: [Int] -> [Int]

That's the type signature (like a C prototype). Now we need the declaration. Because you are learning Haskell lets define this function without using any of the built in operations. What do we do when the input list is empty? Return an empty list!

timothyylim [] = []

What do we do when the list has at least one element?

timothyylim (firstElement : restOfList) =
    -- What goes here?

Well we want to check if someFilterFunction firstElement is true and include that element along with the rest of the filtered list.

    if someFilterFunction firstElement
        then firstElement : timothyylim restOfList

And if it is false, then we just want to return the rest of the filtered list without this element.

        else timothyylim restOfList

At this point we're done - we have a new function timothyylim that applies someFilterFunction to a list and generates a new list. There was no need to look at Prelude functions such as takeWhile - we did this using only language primitives including (in order of introduction) a type signature, case-by-case function declaration, pattern matching, if-then-else statements, function application, list concatenation, and primitive recursion.

In Real Use

In Haskell there is already a definition of a function named filter. It's like our filter except you'd pass in the filter function someFilterFunction as a parameter. So we could say:

timothyylim inputList = filter someFilterFunction inputList

Or equivalently:

timothyylim = filter someFilterFunction

Most of the time if your solution is a manual primitive recursive function, such as the timothyylim function above, then there's already a higher order function (i.e. a function that takes another function as a parameter) in Prelude that can do the job for you (see folds, maps, filters, and zips).

Upvotes: 2

Related Questions