15.08.2013 Views

General Computer Science 320201 GenCS I & II Lecture ... - Kwarc

General Computer Science 320201 GenCS I & II Lecture ... - Kwarc

General Computer Science 320201 GenCS I & II Lecture ... - Kwarc

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

val it = [2,3,4,5] : int list<br />

Question: What is happening here, we define a function by itself? (circular?)<br />

c○: Michael Kohlhase 64<br />

A constructor is an operator that “constructs” members of an SML data type.<br />

The type of lists has two constructors: nil that “constructs” a representation of the empty list,<br />

and the “list constructor” :: (we pronounce this as “cons”), which constructs a new list h::l<br />

from a list l by pre-pending an element h (which becomes the new head of the list).<br />

Note that the type of lists already displays the circular behavior we also observe in the function<br />

definition above: A list is either empty or the cons of a list. We say that the type of lists is<br />

inductive or inductively defined.<br />

In fact, the phenomena of recursion and inductive types are inextricably linked, we will explore<br />

this in more detail below.<br />

Defining Functions by Recursion<br />

SML allows to call a function already in the function definition.<br />

fun upto (m,n) = if m>n then nil else m::upto(m+1,n);<br />

Evaluation in SML is “call-by-value” i.e. to whenever we encounter a function applied to<br />

arguments, we compute the value of the arguments first.<br />

So we have the following evaluation sequence:<br />

upto(2,4) 2::upto(3,4) 2::(3::upto(4,4)) 2::(3::(4::nil)) = [2,3,4]<br />

Definition 92 We call an SML function recursive, iff the function is called in the function<br />

definition.<br />

Note that recursive functions need not terminate, consider the function<br />

fun diverges (n) = n + diverges(n+1);<br />

which has the evaluation sequence<br />

diverges(1) 1 + diverges(2) 1 + (2 + diverges(3)) . . .<br />

Defining Functions by cases<br />

c○: Michael Kohlhase 65<br />

Idea: Use the fact that lists are either nil or of the form X::Xs, where X is an element and<br />

Xs is a list of elements.<br />

The body of an SML function can be made of several cases separated by the operator |.<br />

Example 93 Flattening lists of lists (using the infix append operator @)<br />

fun flat [] = [] (* base case *)<br />

| flat (l::ls) = l @ flat ls; (* step case *)<br />

val flat = fn : ’a list list -> ’a list<br />

- flat [["When","shall"],["we","three"],["meet","again"]]<br />

["When","shall","we","three","meet","again"]<br />

37

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!