Search code examples
sml

Return a list of even numbers in SML


I have been learning SML, which has proven to be quite the undertaking. I am trying to create a function that takes in a list of integers then returns only the even numbers within that list.

Here is what I have so far:

fun isEven [] = [] |
    val evenList            
    if x mod 2 = 1 then //append to evenList

I am very stuck on what I'm supposed to be doing next. Can anyone shed some light on this?


Solution

  • In this example (and for most list-processing problems), it is often easiest to begin by considering two possibilities: either the list is empty, or it is not. When the list is empty, the problem is probably trivial to solve. When the list is not empty, you can deconstruct the list into two pieces: the first element (the "head"), and the rest of the elements (the "tail").

    In code, we can write many different versions of a function depending what the input looks like. Below I'm pattern matching on the input and writing two different function bodies, depending on whether the input is empty or not. When it is not empty, the head of the list is bound to a variable x and the tail is bound to a variable xs:

    fun f []        = (* ... empty case ... *)
      | f (x :: xs) = (* ... non-empty case ... *)
    

    Under this "idiomatic" approach, you can then ask: how do I solve the problem recursively when the list is non-empty? That is, is it possible to apply the same function to the tail of the list, and use that to construct the final answer?

    fun f []        = (* ... TODO: trivial when list is empty ... *)
      | f (x :: xs) =
          let
            val foo = f xs
          in
            (* ... TODO: how to use `foo`? ... *)
          end
    

    At this point, I'll leave the rest to you. Try to fill in the gaps: What does foo represent in your problem? What do you need to do with the head element, x?