OCaml
OCaml
安装OCaml
1 | Homebrew |
然后安装OCaml编译器
1 | environment setup |
然后OCaml就能够运行了,在终端输入:
1 | which ocaml |
1. OCaml Top-level
1.1 Types and Values
1 | 42;; |
Dissect:
Reading right to left:
42
is the value
int
is the type of the valueValue don’t have a name, hence use the symbol
-
Bind the value with a let func
1 | let x = 42;; |
Here the value 42 is bound with name, so use
val
here
1.2 Functions
A function can be defined like:
1 | let increment x = x + 1;; |
increment
is the identifier to which the value was bound
int -> int
is the type of the value, Take aint
as input –> retun a int as output
<fun>
is a placeholder,<fun>
itself is not a value, just indicates an unprintable function value.
Call a func
1 | increment 0 ;; |
1.3 Loading code in toplevel
Load the code in the toplevel with #use
.
1 | #use "mycode.ml";; |
2. Compiling OCaml
Manually:
1 | mkdir hello-world |
Ocaml do not need to have main func like java…
Dune:
Create a file named dune
1 | (executable |
EX: for file hello.ml
1 | $ dune build hello.exe |
3. Expressions
3.1 Primitive Types and Values
Types:
Integers, floating-point numbers, characters, strings, and booleans.
Type Int
: +
, -
, *
, /
, and mod
.
1 | 9/1 |
Type float
: (must always contain a dot .
)
1 | 3. |
Multiplication in float: *.
1 | 3.14 *. 2. |
OCaml will not auto convert between
int
andfloat
.To convert:
int_of_float
andfloat_of_int
.
Type bool
: true
and false
Type char
: write in single quote: 'c'
Convert bewteen int and char:
char_of_int
andint_of_char
Type string
: write in double quote: "string"
concatenation operator: ^
:
1 | "abc" ^ "def" |
Convert int, float and bool to string:
1 | string_of_int 42 |
Convert from a string:
1 | int_of_string "123" |
There is no char_of_string, but can use index operator:
1 | "abc".[1] |
Operators =
and <>
examine structural equality whereas ==
and !=
examine physical equality.
3.2 If Expressions
Syntax: if e1 then e2 else e3
1 | if 3 + 5 > 2 then "yay" else "boo" |
Expression: like “yay” and “boo” should have the same type.
If
can be nested:
1 | if e1 then e2 |
The final
else
is mandatory.
Dynamic semantics:
If e1
evaluates to true
, and if e2
evaluates to a value v
, then if e1 then e2 else e3
evaluates to v
.
If e1
evaluates to false
, and if e3
evaluates to a value v
, then if e1 then e2 else e3
evaluates to v
.
Static semantics:
If e1
has type bool
and e2
has type t
and e3
has type t
then if e1 then e2 else e3
has type t
.
3.3 Let Expressions
Syntax: let
x = e1 in
e2
x
is an identifier, it must start with lower case,e1
is called the binding expression,e2
is called the body expression.
1 | let x = 42 in x + 1 |
Here we bind a value to the name
x
,then using that binding inside another expression,x+1
.
Dynamic semantics:
To evaluate let x = e1 in e2
:
- Evaluate
e1
to a valuev1
. - Substitute
v1
forx
ine2
, yielding a new expressione2'
. - Evaluate
e2'
to a valuev2
. - The result of evaluating the let expression is
v2
.
Example:
1 | let x = 1 + 4 in x * 3 |
Static semantics:
If e1 : t1
and if under the assumption that x : t1
it holds that e2 : t2
, then (let x = e1 in e2) : t2
.
1 | let x : t = e1 in e2 |
3.4 Scope
The scope of a variable is where the name is meaningful.
1 | let x = 42 in |
3.5 Type Annotations
Syntax: (e : t)
parentheses are required.
A type annotation:
1 | (5 : int) |
4. Functions
4.1 Function Definition
Syntax:
1 | let rec f x1 x2 ... xn = e |
Need
rec
keyword to make the function be recursive
Example 1:
1 | (*Assuem n>0*) |
Example 2:
1 | (** [pow x y] is [x] to the power of [y]. |
If we wanna write down the type:
1 | let rec pow (x : int) (y : int) : int = ... |
Mutually recursive functions can be defined with the and
keyword:
1 | let rec f x1 ... xn = e1 |
Example 3:
1 | (** [even n] is whether [n] is even. |
Syntax for Function Types:
1 | t -> u |
~Take input of type
t
and return output of typeu
~Take first input of type
t1
and second input of typet2
and return output of typeu
4.2 Anonymous Functions
Syntax:
1 | fun x1 ... xn -> e |
fun
is a keyword
Example:
1 | (*Ex1, take one param*) |
left-hand side is the function to be applied
right-hand side is the argument
4.3 Function Application
Syntax:
1 | e0 e1 e2 ... en |
No parentheses needed
Evaluation of
e0 e1 e2 ... en
Evaluate subexpression:
E0 –> v0, … , en –> vn
v0 must be a function:
fun x1 ... xn --> e
Substitute vi for xi in e yielding new expression e’.
Evaluate it: e’ –> v
Example 1:
1 | (fun x -> x + 1) (2+3) |
Left-hand side is Anonymous function already, no need to evaluate
(2 + 3) can be evaluated to 5, the apply to the function
fun
Example 2:
1 | (fun x y -> x - y) (3 * 1)(3 - 1) |
4.4 Polymorphic Functions
The identity function is the function that simply returns its input:
1 | let id x = x |
The
'a
is a type variable: it stands for an unknown type.Just like a regular variable stands for an unknown value.
Type variables always begin with a single quote.
Commonly used type variables include
'a
,'b
, and'c
, which typically pronounce in Greek: alpha, beta, and gamma.