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:
42is the value
intis 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
valhere
1.2 Functions
A function can be defined like:
1 | let increment x = x + 1;; |
incrementis the identifier to which the value was bound
int -> intis the type of the value, Take aintas 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
intandfloat.To convert:
int_of_floatandfloat_of_int.
Type bool: true and false
Type char: write in single quote: 'c'
Convert bewteen int and char:
char_of_intandint_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
elseis 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
xis an identifier, it must start with lower case,e1is called the binding expression,e2is 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
e1to a valuev1. - Substitute
v1forxine2, 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
reckeyword 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
tand return output of typeu~Take first input of type
t1and second input of typet2and return output of typeu
4.2 Anonymous Functions
Syntax:
1 | fun x1 ... xn -> e |
funis 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 --> eSubstitute 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
'ais 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.