SML Manipulating Elements in a Nested List

Viewed 145

I want to be able to manipulate items in a nested list such as [[1,2,3],[4,5],[6,7]]

fun f (nil, _) = nil 

|   f((a :: b), rest) = a;

I wrote the above just to be able to access the first element in the first list but it gives this error

stdIn:29.1-29.28 Error: operator and operand do not agree [tycon mismatch]

operator domain: 'Z list list * 'Y

operand:         'X[INT] list list

I've tried a couple other approaches, but I just don't understand what's going wrong.

1 Answers

to access the first element in the first list

Since there is no question, it is hard to answer. But this bit resembled a struggle point. Without knowing exactly what you want to achieve, here are some examples of functions that operate on lists of lists:


fun firsts [] = []
  | firsts ([]::rest) = firsts rest
  | firsts ((x::xs)::rest) = x :: firsts rest

Trying this:

- firsts [[1,2,3],[4,5],[6,7]];
> val it = [1, 4, 6] : int list

The way it works is that upon the empty list of lists, there are no more first elements, so the empty list of first elements is returned; first [] = []. Upon a list of lists where the first of these inner lists is empty, there is no first element of this list, so first elements of the remaining lists is found, first ([]::rest) = firsts rest. Lastly, for a non-empty list of lists of which the first list is non-empty, the first element of that list, x, is a part of the final result.

You could write this function as:

fun firsts rest = List.map head rest

But since head crashes on empty lists (the function is partial), this is like leaving out the middle pattern. Acknowledging that head is partial and providing a safer "no result" value, you can achieve a very similar result without the bug:

fun safeHead [] = NONE
  | safeHead (x::xs) = SOME x

fun firsts rest = List.mapPartial safeHead rest

Trying this:

- firsts [[1,2,3],[],[4,5],[6,7,8],[],[],[9]];
> val it = [1, 4, 6, 9] : int list
Related