Let's do the same as an exercise within it.

So, I've given you another outline of an external function, init, analogous to

last. It takes a list of t for arbitrary t

returns a list of t. Its not defined of list of empty.

So all you need to do is fill in the triple question marks for the two

patterns. What happens if the list consist of one element and what happens in the

case where list is a general first element y followed by a list ys?

So lets see how we would solve this. The initial part of a list that consists

of a single element would be the empty list.

So, we would return list of empty. The initial part of a list that consists of a

head y and some tail ys. What would that be?

Well, it would certainly contain the head and then we would have a recursive call to

init ys. So, one thing that I've just not yet said

explicitly here but which is important, is that the patterns are actually matched in

sequence. So, what this pattern would match is any

list of a single element. What this pattern then would match is any

list of, length two or more, Because we have already covered lists of

zero and one elements. So that means that the recursive call to

init on that list cannot fail, Because we know that the, the size of ys

is, is at least one. So let's look at another fundamental

operation on lists concatenation. How is concatenation implemented?

Well, you'll remember that if we write xs and then the triple colon for

concatenation ys, That really is the same as the call of the

method triple colon with receiver ys and xs as the argument.

So it's a prepend of xs on top of the right hand side ys.

Very much like the prepend function that you've implemented last week, but now, you

prepend a whole list not just the single element.

To find out how the implementation of that can be done, it's actually just as good to

write a stand-alone function. I've given you the signature of concat

here. So, that will be a function that

concatenates and ys like you see here. How could that be implemented?

Well, so far, everything we did was by a pattern match on the list and question,

But now there are two lists we deal with, xs and ys.

So what list should we pattern match on? Well, the other observation is that, once

we were done with pattern matching typically reconstructed lists from left to

right. We were asking the question, what is the

first element of the result list and what is the remainder.

Now, does the first element of the result list, does it depend on xs or on ys.

Well, clearly it depends on xs. So it makes sense to pair and match in xs.

So, let's do that. We have the standard match on xs.

The empty and the case where the list is nonempty with a head z and a tail zs.

Ys is already taken as a name here. So for the empty list, what should concat

return? Well, obviously, the empty list

concatenated with sum list ys is the list ys,

So that would be our result. If the list is not empty, so it contains a

head z and tail zs. You could, next question is, well what is the first

element of the result list? While it's the first element of xs, and

that would be z and the remainder. While the remainder would simply be the

result of concatenating the rest of the left list, which we call letters now here,

and the right list, ys. So, that gives us the complete

implementation of concat. Now, what is its complexity?

Well, we see that we will need a call of concat for each element of the left list.

So complexity would be correspond to the length of the list excess.

Sometimes we use mathematics notations with the double bars to indicate the size

of something. So now that we have seen concat, let's

look at reverse. How can that be implemented?

Let's try by writing a stand-alone function.

So we would have a function reverse, It take xs,

A list of arbitrary element type t. Gives us back a list that's a reversal of

xs. Let's start with the usual pattern match

on the shape of xs. So if that list is empty, then, the

reversal of an empty list would give the list itself.

If that list is nonempty, let's say consisting of a head element y and a tail

ys. What do we do? Well, one thing we know is that the list

will end with the element y. The first element becomes the last element

and before that, or before that, we just have a recursive call of reverse, ys and

then comes the head element, y, in the second list concatenated.

So that would be the definition of reverse.

So the next question is, given that definition, what is its complexity?

Well, let's have a look. We know that concatenation is linear,