Hey, im very new to SML and programming alltogether, i want to write a function that combine within lists, such that [x1,x2,x3,x4,...] = [(x1,x2),(x3,x4),...] Any hints or help for me to go in the right direction is highly appreciated.
let rec pairs = function
| [] -> []
| [x] -> []
| x1::x2::rest -> (x1, x2)::(pairs rest)
By looking at the problem it becomes apparent that we will probably want to process the input two items at a time.
So let's look at what we want to do with each pair: If x1 and x2 are the items we're currently looking at, we want to put the pair (x1, x2)
into the list we're creating. If xs
is the list of items that come after x1
and x2
, we want the pair (x1, x2)
to be followed by the result of "combining" xs. So we can write our combine function as:
fun combineWithin (x1::x2::xs) = (x1, x2)::(combineWithin xs)
However this definition is not yet complete. We're only looking at the case where xs
has at least two items. So we need to ask ourself what we want to do in the other two cases.
For the empty list it's easy: The result of combining the empty list, is the empty list.
For a list with only one item we can either also return the empty list, or raise an error (or possibly pair the one item with itself). In other words: we need to decide whether combineWithin [1,2,3]
should return [(1,2)]
or [(1,2), (3,3)]
or throw an error.
If we decide we want the former, our function becomes:
fun combineWithin (x1::x2::xs) = (x1, x2)::(combineWithin xs)
| combineWithin _ = []