With Non-greek letters

Alpha letters (`'a`

, `'b`

, etc are reserved for generic type.

```
datatype 'a list = nil | :: of 'a * 'a list
infix ::
```

- "alpha" is a type variable (parameter of list)

We say: int list is an instance of 'a list

```
datatype ('a, 'b) either = Left of 'a | Right of 'b
You can't write val y: a' = ...
```

Another example:

```
val m = ([], [])
m: 'a list * 'b list
val m = "string":[]
[] is still 'a list but m is string list
we instanciated 'a to string
[] :: [] is 'a list list
because 'b is instanciated to 'a
[] :: [1]
You will get an error
We say: 'a list does not unify with int
```

```
datatype 'a tree = Empty | Node of 'a tree * 'a * 'a tree
(* trav: 'a tree -> 'a list*) a polymorphic function
fun trav (Empty : 'a tree) : 'a list = []
| trav (Node(l, x, r)) = trav l @ x :: trav r
op@ : 'a list * 'a list -> 'a list
```

```
fun zip([] : 'a list, _ : 'b list) : ('a * 'b) list = []
| zip(_, []) = []
| zip(x::xs, y::ys) = (x, y) :: zip(xs, ys)
```

```
datatype 'a option = NONE | SOME of 'a
(* lookup : (('a * 'a -> bool) * 'a * 'b list) -> 'b option *)
fun lookup(_, _, []) = NONE
| lookup(eq, x, (a, b) :: rest) = if
eq(x, a) then SOME b else lookup (eq, x, rest)
```

Sample Code

```
L = [(1, "hi")]
lookup(op=, 1, L) : string option
lookup((fun(x, y) => x=y) 1, L) : string otion
lookup(op=, 2, L) : string option
```

The type check happens before code run, so `NONE`

has `string option`

as type
SML checks expression by finding the most general type that consistent with the constraints. If it is not possible, then ill-typed, and will generate type error.

```
fun square x = x * x
square: int -> int
fun square x : real = x * x
square: real -> real
```

If SML can't figure out if it is `int`

or `real`

, make it into int.

```
fun loop x = loop x
loop: 'a -> 'b (function of this type always loop)
fun id x = x
id: 'a -> 'a (function of this type is either loop or identity)
fun fastloop x = fastloop (fastloop x)
fastloop : 'a -> 'a (loop an fastloop are entential equivalent)
fun twice f = f(f 0)
twice: (int -> int) -> int
((id twice) square) : int
((twice id) square) is ill typed
fun bind (f, SOME x) = f x
| bind (_, NONE) = NONE
bind: ('a -> 'b option) * 'a option -> 'b option
fun f x = f (0, true)
f: int * bool -> 'a
fun g x = g(x, x) not well typed
g is not well typed, as 'a cannot be unified with 'a * 'a
```

Table of Content