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 t
val 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 -> t2
if ... 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 : 'a
id : 'a -> 'b ; x : 'a
'b = 'a
(id
returns x
)id : 'a -> 'a
let rec loopr x = loopr (x+1)
loopr : 'a
loopr : 'a -> 'b ; x : 'a
x : int ; 'a = int
(x
is passed as an argument to +
)loopr : int -> 'b
exp : 'a
exp : '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 -> float
let rec search elt lst = match lst with
| [] -> false
| h::t -> if h=elt then true
else search elt t
search : '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 expected
cs2041.org