- fun addto (l,v) =
= if null l then nil
= else hd l + v :: addto (tl l,v);
val addto = fn : int list * int -> int list
addto ([1,2,3],2);
val it = [3,4,5] : int list
- addto ([1,2,3],~2);
val it = [~1,0,1] : int list
This is an SML function in my slides. I don't get how (l+v) can work here. But it works actually:
addto ([1,2,3],2);
val it = [3,4,5] : int list
I am thinking it goes something like that:
addto([1,2,3],2);
addto([2,3], 2);
addto([3], 2);
addto([],2)
now it's actually l nill so it returns it to addto([3], 2);
But what does hd l + v :: addto (tl l,v);
mean anyway;
I thought that the "cons" operator ::
has to be defined something like :
<list_object_of_a_certain_type> ::
And here my pseudo-name <list_object_of_a_certain_type> is actually integers in the example with addto([1,2,3],2).
But inside my function we have the phrase (l+v :: ..) while l is a list and v is an int so what is l+v
?
p.s I am a complete beginner so forgive me if it all too simple
First ::
is defined as:
datatype 'a list = nil | :: of 'a * 'a list
So, for instance, 1 :: [2, 3]
is the list [1, 2, 3]
.
Then in your code, your expression is interpreted as:
((hd l) + v)) :: (addto (tl l,v))
So basically, your function can be rewritten as follows:
fun addto (l,v) =
if null l then nil (* if l is empty the result is the empty list *)
else let
val head = hd l (* take the first element of list l *)
val sum = head + v (* then add it v *)
val result_tail = addto (tl l,v) (* and compute x + v for all x in the tail of my list *)
in
sum :: result_tail (* the result is the sum I just computed followed by what the recursive call gave me *)
end
Finally, note that in most cases, you don't need functions such as null
or head
because we write functions with pattern matching construction. This greatly enhances readability and it is often the case that it suppresses the need for such functions. For instance, addto
can be rewritten more simply as:
fun addto ([], _) = []
| addto (x :: tl, v) = (x + v) :: addto (tl, v)
Simpler isn't it?