## ML Types: Practice sheet

Determine the types of the following ML types and objects, or state that they are not type correct. For the functions, be sure you understand how they work. This is NOT TO HAND IN, as the assignment can be done trivially by typing each of them into the ML interpreter.
• ([2,3],[4,5,5]); int list * int list
• [(2,3), (4,5)]; (int * int) list
• ([2,3],[4.1,5.2,5.3]); int list * real list
• [(2.1,3), (4.2,5)]; (real * int) list
• [(2.1,3), (4,5.2)]; Error. The first element of the list is real*int, and the second is int*real.
• [([2],3), ([4,5],6)]; (int list * int) list
• ([(2),3], [(4,5),6]); Error.
• fun min(X,Y) = if X < Y then X else Y;
fn : int * int -> int;
• fun safeDivide(X,Y) = if Y = 0 then false else X/Y;
Error. Actually, the error encountered here is not the one I expected. The / divide is defined as taking real arguments (integer divide is called div). The definition "fun safeDivide(X,Y) = if Y = 0 then false else X div Y;" gives an error because the if branches do not agree. The definition "fun safeDivide(X,Y) = if Y = 0.0 then false else X/Y;" gives an error because in ML equality is not defined for reals.
• fun pairToList(X,Y) = [X,Y];
fn : 'a * 'a -> 'a list;
• fun pairToPairOfLists(X,Y) = ([X],[Y]);
fn :'a * 'b -> 'a list * 'b list;
fn : 'a list -> 'a list list;
• fun repeat2a(f,x) = f(f(x));
fn : ('a -> 'a) * 'a -> 'a.
• fun repeat2(f) = fn(x) => f(f(x));
fn : ('a -> 'a) -> 'a -> 'a
• fun repeatN(f,n) = fn(x) => if (n=0) then x else f(repeatN(f,n-1)(x));
That is repeat(f,1)(x) = f(x). repeat(f,2)(x) = f(f(x)). repeat(f,n)(x) = f(f(f ... n times (f(x)) ...))
fn : ('a -> 'a) * int -> 'a -> 'a
• repeatN(fn(x) => x+3,4);
fn : int -> int;
• fun repeat f n x = if n=0 then x else f(repeat f (n-1) x);
(Basically the same as repeatN, but this is how a real ML programmer would write it.)
fn : ('a -> 'a) -> int -> 'a -> 'a
• repeat tl;
fn : int -> 'a list -> 'a list
• repeat tl 3;
fn : 'a list -> 'a list;
• repeat tl 3 [10,20,30,40];
int list
• ``` fun f [X] = [X] | f(X::Y) = g(X::Y)::f(Y)
and
g(_::Y) = hd(f(Y));
```
f = fn : 'a list -> 'a list;
g = fn : 'a list -> 'a