A program is a sequence of expressions that are evaluated in order.
Every expression has a unique value and type.
We’ve seen primitive types and operators, let (rec) expressions, function values and types, and product types (tuples).
Ocaml has a language for specifying types: ->, *, 'a.
Structured data (tuples, lists) can be accessed through pattern matching.
Ocaml has a built-in type, unit that has only one value, ().
What good is that?
To signal that a computation doesn’t result in a useful value:
val print_string : string -> unit
Most interesting programs don’t fit in a single file.
In OCaml, we can refer to any name bound in file file.ml as File.name
How do we compile? Run ocamlc with all .ml files in order.
#mod_use to leave definitions in a module in utop
Example: searching a list for an element.
let rec search elt lst = match lst with
| [] -> false
| h::t -> if h=elt then true
else search elt tval search : 'a -> 'a list -> bool
How did Ocaml “know” the type of search?
The Ocaml compiler uses an algorithm to infer the type of every identifier.
Initially, assign an identifier “most general type” 'a, 'b, ...'.
While checking the program, refine the type as needed:
t1 -> t2if ... then ... else must have matching branchesmatch v with p1 -> e1 | ... | p𝓃 -> e𝓃, v,p1,…p𝓃 must have matching types, and e1,…e𝓃 must have matching typeslet id x = x
id : 'aid : 'a -> 'b ; x : 'a'b = 'a (id returns x)id : 'a -> 'alet rec loopr x = loopr (x+1)
loopr : 'aloopr : 'a -> 'b ; x : 'ax : int ; 'a = int (x is passed as an argument to +)loopr : int -> 'bexp : 'aexp : 'a -> 'b (due to function keyword)'a = 'c * int (due to (_,0) pattern)'b = float' (due to body of 1st clause, 1.0 : float)b : 'c ; n : int (in 2nd clause pattern)b : float ; 'c = float (b passed as argument to *.)val exp : float * int -> floatlet rec search elt lst = match lst with
| [] -> false
| h::t -> if h=elt then true
else search elt tsearch : 'a
search : 'a -> 'b -> 'c ; elt : 'a ; lst : 'b
(search = fun elt -> fun lst ->...)
lst : 'd list ; 'b = 'd list (due to [] in 1st pattern)
'c = bool (due to body of 1st clause : false : bool)
h : 'd ; t : 'd list (second pattern)
'd = 'a (h and elt are passed to (=) : 'a -> 'a -> bool)
val search : 'a -> 'a list -> bool
Finding a type error…
search1 : 'a -> 'b -> 'c ; elt : 'a ; lst : 'b
lst : 'd list ; 'b = 'd list
'c = 'e list (body of first clause)
h : 'd; t : 'd list
'e list = bool (result (search1 elt t) used as argument to ||)
Error: this expression has type 'a list but an expression of type bool was expectedcs2041.org