There is a more general version of the question that is maybe a little clearer. Instead of specifically working with lists of lists, I'll instead discuss this with the more general type:
'a list -> ('a * 'a) list
This includes your desired signature ('a list) list ->('a list * 'a list) list
as a special case.
It now breaks into three cases: empty lists, lists of a single element, and any other lists. You can't make pairs of elements with the first two, so we'll have those evaluate to an empty list. The remaining case is the interesting one, and looks similar to what you have. However, since you want to pair the first element of the list with all others, you'll need to put that first element back into the list when foo
is recursively called. The end result looks like this:
fun foo [] = []
| foo [x] = []
| foo (x::y::ys) = (x,y)::foo(x::ys)
And when used (in Moscow ML):
- foo [[2,3,4], [1,2], [6,7,8]];
> val it = [([2, 3, 4], [1, 2]), ([2, 3, 4], [6, 7, 8])] :
(int list * int list) list