-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOCaml Cheat Sheet.ml
208 lines (171 loc) · 7.8 KB
/
OCaml Cheat Sheet.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
; (* Separator in the interpreter. *)
;; (* Mostly used when interpreting OCaml, tells it that it to stop. *)
(* Gets definitions from the given package. *)
open List;; (* opens the List package which allows you to use List definitions. *)
(* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= *)
char --> Example: 'a'
float --> Example: 2.14
3.0 +. 0.2;; (* Operators for floating numbers must have a dot after the operator. *)
int --> Example: 3
(* Items are separated by ; and the types must be the same! *)
list --> Example: [1;2;3]
['a';'b';'c'] (* List of characters. *)
let l2 = [1;2;3];; (* Sets the name l2 to the given list. *)
4::5::6::[];; --> -: int list [4;5;6]
4::5::[6];; --> -: int list [4;5;6]
let l1 = ['a';'b';'c'];;
(* Head of the list, returns the first element of a list. *)
hd l1;; --> char = 'a'
(* Tail of the list, returns the list without the first element. *)
tl l1;; --> char list = ['b';'c']
(* Appends 2 lists together. Version 1. *)
let rec append2 l1 l2 =
if l1 = [] then l2 (* If l1 is an empty list then return l2. *)
else hd l1 :: append2 (tl l1) l2;; (* Take the first element of l1 and combine it with *)
(* Appends 2 lists together. Version 2. *)
let rec append2 l1 l2 =
match l1 with
| [] -> 12 (* If l1 is an empty list then return l2. *)
| _ -> hd l1 :: append2 (t1 l1) l2;;
append2 [1;2] [3;4] --> -: int list = [1;2;3;4]
(* Check if an item is in a list. *)
let rec member x l =
if l = [] then false
else if x = hd l then true
else member x (tl l);;
member 1 [1;2;3];; --> -: bool = true
member 4 [1;2;3];; --> -: bool = false
(* Arrays, can allow you to directly access the elements and index. *)
let five_primes = [| 2; 3; 5; 7; 11 |];; (* An array example of 5 ints. *)
five_primes.(2);; --> -: int = 5 (* Returns the number at index 2. *)
five_primes.(2) <- 4 --> -: unit = () (* Changes the value of index 2 to 4. *)
five_primes;; --> -: int array = [|2; 3; 4; 7; 11|]
(* Tuples, consists of values (0 or more), enclosed in parentheses and separated by commas. Can have different types for each element. *)
(1, 2);; --> -: int * int (1, 2)
(1, "Hello");; --> -: int * string = (1, "Hello")
(1, "Hello", 1.234);; --> -: int * string * float = (1, "Hello", 1.234) (*Example of a 3-dimensional tuple. *)
(10234, "Sa");; --> -: int * string = (10234, "Sa")
type 'a tree = Empty | Node of 'a * 'a tree * 'a tree;;
let myt1 = Empty;;
let myt2 = (1, Empty, Empty);;
let myt2 = (2, myt1, Empty);;
let myt3 = (3, myt2, Empty);;
let myt4 = (4, myt2, myt3);;
("Hg", 80);; --> -: string * int = ("Hg", 80)
let mercury = ("Hg", 80);; (* Set this tuple to a name *)
(* Gets the first value of the tuple. *)
fst mercury;; --> -: string = "Hg"
(* Gets the second value of the tuple. *)
snd mercury;; --> -: int = 80
(* Records, fields in a record has a name unlike tuples. The order doesn't matter unlike tuples. *)
type element = {name: string; atomic_number: int; atomic_weight float};;
let mercury = { atomic_number = 80; name = "Hg"; atomic_weight = 200.592};; (* Makes a record that we defined above. *)
mercury.name;; --> -: string = "Hg"
mercury.atomic_number;; --> -: int = 80
(* mutable - This keyword allows you to make a certain field in a record changeable once set. *)
type sale_item = {name: string; mutable price: float};; (* Makes a new record with price being mutable, which means it can change! *)
let my_item = {name = "bike"; price = 699.99};;
my_item.price;; --> -: float = 699.99
my_item.price <- 599.99;;
my_item.price;; --> -: float = 599.99
(* References, kind like a pointer. *)
let x = ref 3;; --> val x : int ref = {contents = 3}
!x;; --> -: int = 3 (* Gets the value of x. *)
x := !x + 1;; (* Changes the value of x. *)
!x;; --> -: int = 4 (* Gets the value of x. *)
(* | mean or *)
type weekday = Sun | Mon | Tue | Wed | Thu | Fri | Sat;;
type yearday = YMD of int * int * int | YD of int * int;;
let a = YMD(2020, 3, 2);; (*Creates a type yearday defined above. *)
(* IEmpty represents type inttree with no data. It can be named anything. *)
type inttree = IEmpty | IntNode of int * inttree * inttree;;
let it1 = IntNode(1, IEmpty, IEmpty);;
let it2 = IntNode(2, it1, IEmpty);;
let it3 = IntNode(3, it2, it1);;
type 'a tree = Empty | Node of 'a * 'a tree * 'a tree;; (* Polymorphic version of the type above. *)
let t1 = Node('a', Empty, Empty);;
let mt2 = Node (1, Empty, Empty);;
let Node(v, l, r) = mt2 (* Set the values of mt2 to the give names (deconstruction) *)
l;; --> -: int tree = Empty
v;; --> -: int = 1
let rec inorder t =
match t with
| Empty -> []
(* If it's a Node with 3 parameters (Names can be anything). Then do in order for the left side, then put the root & declare it as a list, then do the right side.*)
| Node(v, left, right) -> inorder left @ [v] @ inorder right;; (* @ = append *)
let rec preorder t =
match t with
| Empty -> []
| Node(v, left, right) -> [v] @ preorder left @ preorder right;;
let rec postorder t =
match t with
| Empty -> []
| Node(v, left, right) -> postorder left @ postorder right @ [v];;
(* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= *)
(* Physical Equivalence *)
== --> Example: 2 == 2
2 == 3 --> false
let l1 = [1;2]; l1 == l1 --> true
(* Structural Equivalence *)
= --> Example: [1] = [1]
[1;2;3] = [1;2;3] --> true
let l1 = [1;2]; l1 = [1;2] --> true
(* List Construction. *)
::
(* Concatenation or appends lists together *)
@
[1;2]@[3;4];; --> -: int list = [1;2;3;4]
(* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= *)
(* Parameters don't have () or commas in between. *)
max 1 2;; --> -: int = 2
let --> (* Sets things to names. *)
let hi = 3;; (* Sets the name hi to int 3. *)
let f3() = 3;; (* Put () if there is no parameters. *)
(* Functions [4 styles / types] *)
let average = fun x y -> (x +. y) /. 2.;; (* Type 1, allows polymorphism. *)
average 2. 3.;; --> -: float = 2.5
let average2 x y = (x +. y) /. 2.;; (* Type 2, allows polymorphism. *)
average2 2. 3.;; --> -: float = 2.5
let average3: float -> float -> float = fun x y -> (x +. y) /. 2.;; (* Type 3, useful for setting the type of the parameters specifically! *)
average3 2. 3.;; --> -: float = 2.5
let average4 (x:float) (y:float) : float = (x +. y) /. 2.;; (* Type 4, more readable then Type 3. *)
average4 2. 3.;; --> -: float = 2.5
(* Local names using let - in system. *)
let triangle_area a b c =
let s = (a +. b +. c) /. 2.0 in (* Local name. *)
sqrt(s *. (s -. a) *. (s -. b) *. ( s -. c));;
triangle_area 3. 4. 5.;; --> -: float = 6.
(* Function Recursion using rec This tells OCaml that it will be a recursive function. *)
let rec fact x =
if x = 0 then 1
else x * fact(x - 1);;
fact 0;; --> -: int = 1
fact 1;; --> -: int = 1
fact 2;; --> -: int = 2
fact 3;; --> -: int = 6
fact 4;; --> -: int = 24
(* Using match-with statement. | = New case or separator. _ = Default. *)
let rec fact x =
match x with
| 0 -> 1
| _ -> x * fact(x - 1);;
fact 0;; --> -: int = 1
fact 1;; --> -: int = 1
fact 2;; --> -: int = 2
fact 3;; --> -: int = 6
fact 4;; --> -: int = 24
(* This will throw an error because it doesn't have a default ( _ ). *)
let foo x =
match x with
| 0 -> "zero"
| 1 -> "one";;
(* Recursive helper functions, *)
let fib n =
let rec fib_helper f1 f2 i =
if i = n then f1
else fib_helper f2 (f1 + f2) (i + 1) in
fib_helper 0 1 0;;
fib 0;; --> -: int = 0
fib 1;; --> -: int = 1
fib 2;; --> -: int = 1
fib 3;; --> -: int = 2