Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New to SML / NJ. Adding numbers from a list of lists

Define a function which computes the sum of all the integers in a given list of lists of integers. No 'if-then-else' or any auxiliary function.

I'm new to to functional programming and am having trouble with the correct syntax with SML. To begin the problem I tried to create a function using pattern matching that just adds the first two elements of the list. After I got this working, I was going to use recursion to add the rest of the elements. Though, I can't even seem to get this simple function to compile.

fun listAdd [_,[]] = 0
|   listAnd [[],_] = 0
|   listAnd [[x::xs],[y::ys]] = x + y;
like image 635
user2777383 Avatar asked Oct 02 '22 23:10

user2777383


2 Answers

fun listAdd [] = 0
  | listAdd ([]::L) = listAdd L
  | listAdd ((x::xs)::L) = x + listAdd (xs::L)

should do what it looks like you want.

Also, it looks like part of the problem with your function is that you give the function different names (listAdd and listAnd) in different clauses.

like image 68
qaphla Avatar answered Oct 06 '22 00:10

qaphla


For the sake of simplicity, I'd say you probably want this :

fun listAdd : (int * int) list -> int list

Now, I would simply define this as an abstraction of the unzip function :

fun listAdd ls :
    case ls of 
        [] => 0
      | (x,y) :: ls' => (x + y) + (listAdd ls')

I think there is no point in taking two separate lists. Simply take a list that has a product of ints. If you have to build this, you can call the zip function :

fun zip xs ys :
    case xs, ys of
        [], [] => []
      | xs, _ => []
      | _, ys => []
      | x::xs', y::ys' => (x,y) :: (zip xs' ys')

In general, if you really wanted, you can write a far more abstract function that is of the general type :

fun absProdList : ((`a * `b) -> `c) -> (`a * `b) list -> `c list

This function is simply :

fun absProdList f ls =
    case l of 
        [] => []
      | (x,y) :: ls' => (f (x,y)) :: (absProdList f ls')

This function is a supertype of the addList function you mentioned. Simply define an anonymous function to recreate your addList as :

fun addList' ls =
    absProdList (fn (x,y) => x + y) ls

As you can see, defining the generic type-functions makes specific calls to functions that are type-substitutions to the general one far easier and much more elegant with the appropriate combination of : Currying, Higher-Order Functions and Anonymous Functions.

like image 30
Juspreet Sandhu Avatar answered Oct 06 '22 00:10

Juspreet Sandhu