Search code examples
functional-programmingsmlhigher-order-functionsfold

How to do an addition on a list with a condition?


I have a university course about functional programming, where I use SML. As a preparation for the exam, I am working on some of the older exam sets without solutions.

One of the only questions I really have problems with is the following question using foldl:

Consider the program skeleton: fun addGt k xs = List.foldl (...) ... xs; Fill in the two missing pieces (represented by the dots ...), so that addGt k xs is the sum of those elements in xs, which are greater than k. For example, addGt 4 [1, 5, 2, 7, 4, 8] = 5 + 7 + 8 = 20

I am sure this is really easy, but I have a very hard time understanding the foldl and foldr functions.

What I have now is the following (which seems to be very wrong if you ask my compiler!):

fun addGt(k,xs) = List.foldl ( fn x => if x > k then op+ else 0) 0 xs;

I would really appreciate some help with this question, and maybe a very short comment which would cast some light on the foldl and foldr functions!


Solution

  • A solution that I just though of is the following:

    fun addGt(k, xs) = List.foldl (fn (x, y) => if x >= 5  then x + y else y) 0 xs;
    

    But let me explain. First of all check the type of the List.foldl function, it's:

    ('a * 'b -> 'b) -> 'b -> 'a list -> 'b
    

    So List.foldl is a curried function that takes as first parameter another function of type ('a * 'b -> 'b). You used (fn x => if x > k then op+ else 0) which has type int -> int. You should instead provide List.foldl with a function that takes a tuple of type int * int and returns an int, so something like this: (fn (x, y) => do stuff). That's why your code didn't compile, you passed a wrong type of function in foldl.

    Now you can think of foldl this way:

    foldl f b [x_1, x_2, ..., x_(n - 1), x_n] = f(x_n, f(x_(n - 1), ..., f(x2, f(x1, b)) ...)) where f is a function of type ('a * 'b -> 'b), b is something of type 'b and the list [x_1, x_2, ..., x_(n - 1), x_n] is of type 'a list.

    And similar for foldr you can think it in this way:

    foldr f b [x_1, x_2, ..., x_(n - 1), x_n] = f(x_1, f(x_2, ..., f(x_(n - 1), f(x_ n, b))