240 likes | 371 Views
Crash course on SML Wojciech 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.
E N D
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 of Null => 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, ^, <= ...