With Non-greek letters
Alpha letters ('a
, 'b
, etc are reserved for generic type.
datatype 'a list = nil | :: of 'a * 'a list
infix ::
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