smlsmlnj

Currying and summation of two lists of varying size


I'm self-learning SML and am currently am stuck with the concept of recursion between two lists of varying sizes.

Suppose you have two int lists of varying size, and a function that multiplies two numbers, like so:

val mul = fn(a, b) => a * b;

I want to use this function to be passed as a parameter into another function, which multiplies the numbers in the same index recursively until at least one of the lists is empty. So

val list1 = [1, 3, 5, 7]; 
val list2 = [2, 6, 3];

would be passed through that same function with mul and 35 would be returned, as 1*2 + 3*6 + 5*3 would be calculated.

My knowledge of how SML works is a bit limited, as I'm not exactly sure how to carry the result of the sum forward during the recursion, nor how to handle the base case when one of either lists terminates early. Could someone point me in the right direction in thinking of this problem?


Solution

  • You can use pattern-matching and recursion to operate over two lists simultaneously. You then need an accumulator to pass the sum along.

    fun mulAndSum acc ([], []) = ...
      | mulAndSum acc ([], _) = ...
      | mulAndSum acc (_, []) = ...
      | mulAndSum acc ((x::xs), (y::ys)) = mulAndSum (...) (xs, ys)
    

    Then when you call the function, you provide zero as the initial state of the accumulator.

    mulAndSum 0 ([1, 3, 5, 7], [2, 4, 6])