Post on 05-Jan-2016
description
Crash course on SMLWojciech Moczydłowski
• SML – functional programming language
• Complete formal semantics
• Extremely convenient for writing compilers, interpreters, provers and 611 homeworks
• OCaml, based on SML, is practical and used in industry
SML - ideology
• 3 worlds – expressions, values and types.
• Values have types, i.e. 0 : int, “asd” : string
• Expressions have types as well, i.e. 3+4 : int, fact : int -> int
• Expressions evaluate to values
SML types
• Some types:– int, string, char– int*int, int*string– int -> int, int*int -> int– int -> int -> int– int list– ‘a list– ‘a -> ‘b -> ‘a
Interpreter
- 2+2;
val it = 4 : int
- 23+17;
val it = 40 : int
- “611 rules”;
val it = “611 rules” : string
- ~17 + 17;
val it = 0 : int
- (17, “a”);
val it = (17, “a”) : int * string
Definitions
- val i = 10;
val i = 10 : int
- val j = i + i;
val j = 20 : int
- val s = Int.toString(j);
val s = “20” : string
- val t = (i, i + 1, i + 2);
val t = (10, 11, 12) : int * int *int
- val q = #2 t;
val q = 11 : int
Datatypes
- datatype Bool = True | False
- datatype Color = Red | Black
- datatype Nat = Zero | S of Nat
- True;
val it = True : Bool
- S(S(Zero));
val it = S(S(Zero)) : Nat
Functions
• fun add(n, m : Nat) : Nat = case n of Zero => m | S(x) => S(add(x, m));• fun mult(n, m) =
case n of Zero => Zero
|S(x) => add(n, mult(x, m))• Evaluation – call by value. • All functions have one argument –
add : Nat * Nat -> Nat mult : Nat * Nat -> Nat
Anonymous functions
• As in lambda calculus, a function can be specified “on fly”
- (fn x => x + 17) 26;
val it = 43 : int;
Large parts of lambda calculus can be expressed.
Polymorphism
- val K = fn x => fn y => x;
val K = fn : ‘a -> ‘b -> ‘a
‘a ‘b are type variables.
- K 6 4;
val it = 6 : int
- K “611” 170;
val it = “611” : string
- K K K;
Polymorphism
- val I = fn x => x;
- val S = fn x => fn y => fn z =>
(x z) (y z);
- val Ap = fn f => fn x => f x;
However, the following won’t type-check:
- val Y = fn f => (fn x => f (x x)) (fn x => f (x x));
- (fn x => x x) (fn x => x x);
Datatypes reloaded
• datatype ‘a option = NONE | SOME of ‘a;
- NONE;val it = NONE : ‘a option;- SOME;val it = fn : ‘a -> ‘a option- SOME 5;val it = SOME 5 : int option;- SOME “Cornell”;val it = SOME “Cornell” : string
option;
Datatypes
- fun div(m, n) = if n = 0 then NONE else SOME (m div n);
- datatype (‘a, ‘b) Either =
Left of ‘a | Right of ‘b;
Recursive polymorphic datatypes
- datatype ‘a Tree = Null |
Node of (‘a Tree) * ‘a * (‘a Tree)
- Node (Node(Null, 5, Null), 3, Null);
- fun sum(t) = case t of
Null => 0
| Node (a, b, c) =>
sum(a) + b + sum(c)
RPD’s
fun size(t) = case t of
Null => 0
|Node(t1, _, t2) =>
size t1 + (size t2) + 1
fun add(t, n) = case t of
Null => Null
|Node(t1, m, t2) =>
Node(add(t1, n), m + n,
add(t2, n))
RPD’s
fun mul(t, n) = case t of
Null => Null
|Node(t1, m, t2) =>
Node(mul(t1, n), m * n,
mul(t2, n))
In general?
RPD’s
fun mapTree(t, f) = case t ofNull => Null
|Node(t1, m, t2) => Node(mapTree(t1, f), f m, mapTree(t2, f))
- fun add(t, n) = mapTree(t, fn m => m + n);- val mul = fn (t, n) => mapTree (t, fn m => n * m);
RPD’s
datatype ‘a list = nil | cons of
(‘a * ‘a list);
Notation:
[] denotes nil
(x::xs) denotes cons (x, xs)
Lists
Some lists:
[]
(1::(2::(3::nil)))
(“a”::”b”::”c”::nil)
Another notation:
[a, b, c] = a::b::c::nil
[1,2,3], [“a”, “b”, “c”]
Lists
- fun length(l) = case l of
[] => 0
|(x::xs) => 1 + length xs;
- fun hd [] = raise Fail “Empty”
|hd(x::xs) = x;
- fun tl [] = raise Fail “Empty”
|tl (x::xs) = xs;
Lists
- fun map(f, l) = case l of
[] => []
|(x::xs) => f x ::(map f xs);
Modules
signature SET = sig
type ‘‘a set
val empty : ‘‘a set
val insert : ‘‘a -> ‘‘a set -> ‘‘a set
val elem : ‘‘a -> ‘‘a set -> bool
end
Modules
structure Set :> SET= struct
type ’’a set = ‘‘a list
val empty : ‘‘a set = []
val insert : ‘‘a -> ‘‘a set -> ‘‘a set = fn x => fn y => x::y
val elem : ‘‘a -> ‘‘a set -> bool = ...
end
Accessing structure elements
- Set.insert, Set.add ....
- open Set;
- insert, add, ...
Standard library
• Many useful structures
• List :> LIST
hd, tl, last, map, find, filter...
• Option :> OPTION
option, isSome, val Of, filter...
• String :> STRING
size, isSubstring, ^, <= ...