restructure + lecutre 07

This commit is contained in:
SowinskiBraeden committed 2026-02-19 11:59:58 -08:00
1 parent b8c19aa341
commit 7c3198fee4
96 files changed
+458 -4

No files matched your search

+279
View File
@@ -0,0 +1,279 @@
(*
COMPILE = ocamlc -o outfile infile.ml
UTOP = #use "filename.ml";;
*)
(*
Ocaml is thankfully garbage collected
Expressions must end with double semi colon
e.g. let name = "Bread";;
expressions can be evaluated to a value
ocaml is a statically typed and strongly typed language
meaning that at compile time the type of a variable will
be known. The compiler uses type inference to determine the
type of a variable that you dont need to specify;
e.g.
*)
(* string type *)
"Hello World";;
(* character type *)
'A';;
(* integer type *)
50;;
(* floating type *)
20.3;;
(*
OPERATIONS
you have basic operations such as
+, -, *, /, that works with integer types
to do these operations with floating point
numbers you need to use the following
+., -., *., /., notice the "." after the operator
-----------------------------------------------
MODULE does not use the % sign
use "mod" e.g.
3 mod 2;; - : int = 1 (* evaluates to 1 *)
----------------------------------------------
NOT uses the word "not" instead of "!" e.g.
not (1 < 2);; - : bool = false
*)
(*
COMPARATORS
standard and, or comparisons e.g.
a && b, a || b
you can use >, <, but the comparator uses a
single equal sign. e.g.
1. = 2.;; - : bool = false (* evaluates to false *)
-----------------------------------------------
NOT EQUALS
to check for inequality use "<>", e.g.
1. <> 2.;; - bool = true (* evaluates to true since 1. and 2. are not equal *)
*)
(*
STRING CONCATONATION
use the "^" (carrot operator) to concat strings e.g.
*)
"Braeden" ^ " " ^ "Sowinski"
(*
FUNCTIONS
define a function square that takes in a
parameter x and returns x * x
*)
let square x = x * x;;
square 5;;
(* evaluates to 6 *)
let x = 1 in x + 5;;
let add x y = x + y;;
(*
arrows are right associative
name : input -> input -> return type
val add : int -> int -> int = <fun>
so this can be translated to int -> (int -> int)
this means that every function essentially takes in 1 argument
that then returns another functoin that takes in another argument
*)
(* valid *)
add 1 2;;
(* valid *)
(add 1) 2;;
(* invalid *)
(*add (1 2);;*)
(*
Ocaml is functional and there are no loops
such as for or while,
all variables are immutable
*)
let x = 1;;
let x = 2;;
(*
x = 3;; (* cannot reassign, this evaluates as a comparison
therefore variables are immutable *)
*)
(*
RECURSION
recursion is related to mathematical induction,
you typically have a proposition, e.g. P, where we
know P(1) is true, and we assume P(k) is true
where we can proove that P(k + 1) is true
to declare a recursive function you need "rec"
*)
let rec factorial n = if n = 0 then 1 else n * factorial (n - 1);;
let r = (factorial 5);;
print_int r;;
print_endline "";;
(*
tail-recursive
a recursive function is tail-recursive if the recursive
call is the last thing we do, for example, factorial is not
tail-recursive, because we need to multiply n to the recursive call.
non tail-recursive functions are bad since there is potential to bloew
through the stack.
lets consider factorial 3 = 3 * fact 2
= 3 * (2 * fact 1)
= 3 * (2 * (1 * fact 0))
= 3 * (2 * 1)
= 3 * 2
= 6
we can see that this is not tail recursive as we need to store a value for
each part of the iteration, we can solve this by rewriting the function a little
using an accumulator
*)
let rec fact n acc = if n = 0 then acc else fact (n - 1) (n * acc);;
(* we can have primes, e.g. function f, and function f prime or f' *)
let factorial' n = fact n 1;;
let r = (factorial 5);;
print_int r;;
print_endline "";;
let factorial' = fact 1;;
(*
consider the tail-recursive version of factorial, fact'
the signature is fact' n acc
fact' 1 3 = fact' 3 2
= fact' 6 1
= fact' 6 0
as you can see, the stack would not grow
lets combine the functoins into a single one
with nesting
*)
(* final tail-recursive version *)
let fact n =
let rec fact' acc i =
if i = 0 then acc
else fact' (i * acc) (i - 1)
in
fact' 1 n;; (* automatically sets the accumulator to 1 *)
let r = fact 5;;
print_int r;;
print_endline "";;
(* example of a documentation comment *)
(** [gcd a b] returns the greatest common divisor of [a] and [b]
* Requires:[a > 0] and [b > 0]
*)
let rec gcd a b =
if a mod b = 0 then b
else gcd b (a mod b);;
(*
let r = gcd 12 18;;
print_int r;;
print_endline "";; *)
let rec fib n =
if n = 0 then 0
else if n = 1 then 1
else fib (n - 1) + fib (n - 2);;
let r = fib 10;;
print_int r;;
print_endline "";;
(* tail-recursive version *)
let rec fib n =
let rec fib' i a b =
if i = n then a
else fib' (i + 1) b (a + b)
in
fib' 0 0 1;;
let r = fib 10;;
print_int r;;
print_endline "";;
(*
MUTALLY-RECURSIVE FUNCTION
*)
let rec even n =
if n = 0 then true
else odd (n - 1)
and odd n =
if n = 0 then false
else even (n - 1);;
(*
useful stuff
float_of_int 4
int_of_string "123"
*)
let square_root x =
let good_enough y = abs_float (x -. y *. y) < 0.00000000001 in
let rec aux y =
if good_enough y then y
else aux (0.5 *. (y +. x /. y))
in
aux 1.;;
print_float (square_root 2.);;
print_endline "";;
(*
Consider this
create an exponential function
where it calculates e^x
using recursion
*)
+41
View File
@@ -0,0 +1,41 @@
(*
ocamlc -o tinker tinker.ml
^^^ compile command
*)
(* Comments are weird *)
(*
concat takes to paramters a and b and concats them
together while seperated by a space
*)
let concat a b = a ^ " " ^ b;;
(*
describe maps the concat function to each element
in the list to describe the element with "eat"
*)
let describe = List.map (fun f -> concat "eat" f);;
let full_name = concat "Braeden" "Sowinski";;
print_endline full_name;;
let gruit = ["apple"; "banana"; "grape"];;
(*
takes in a list and iterates over elements
to print_endline the element
*)
let print_list_string list =
List.iter print_endline list;;
(*
I think this acts like a main method,
creates the describe list then iterates
and passes to the print_list_string function
*)
let () =
let eating = describe gruit in
print_list_string eating;;
+33
View File
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link rel="Up" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Length</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Module <a href="type_Length.html">Length</a></h1>
<pre><span id="MODULELength"><span class="keyword">module</span> Length</span>: <code class="code">sig</code> <a href="Length.html">..</a> <code class="code">end</code></pre><div class="info module top">
<div class="info-desc">
<p>returns the number of elements in the list <code class="code">l</code> - non tail recursive</p>
</div>
</div>
<hr width="100%">
<pre><span id="VALlength"><span class="keyword">val</span> length</span> : <code class="type">'a list -&gt; int</code></pre>
<pre><span id="VALtest_length"><span class="keyword">val</span> test_length</span> : <code class="type">unit -&gt; unit</code></pre>
<pre><span id="VALlength_tr"><span class="keyword">val</span> length_tr</span> : <code class="type">'a list -&gt; int</code></pre><div class="info ">
<div class="info-desc">
<p>returns the number of elements in the list <code class="code">l</code> - tail recursive</p>
</div>
</div>
<pre><span id="VALtest_length_tr"><span class="keyword">val</span> test_length_tr</span> : <code class="type">unit -&gt; unit</code></pre></body></html>
+27
View File
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title></title>
</head>
<body>
<div class = "index-list">
<ul class="indexlist">
<li><a href="index_values.html">Index of values</a></li>
<li><a href="index_modules.html">Index of modules</a></li>
</ul>
</div>
<table class="indextable module-list">
<tr><td class="module"><a href="Length.html">Length</a></td><td><div class="info">
returns the number of elements in the list <code class="code">l</code> - non tail recursive
</div>
</td></tr>
</table>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of class attributes</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of class attributes</h1>
<table>
</table>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of class types</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of class types</h1>
<table>
</table>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of classes</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of classes</h1>
<table>
</table>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of exceptions</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of exceptions</h1>
<table>
</table>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of extensions</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of extensions</h1>
<table>
</table>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of class methods</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of class methods</h1>
<table>
</table>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of module types</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of module types</h1>
<table>
</table>
</body>
</html>
+24
View File
@@ -0,0 +1,24 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of modules</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of modules</h1>
<table>
<tr><td align="left"><div>L</div></td></tr>
<tr><td><a href="Length.html">Length</a> </td>
<td><div class="info">
returns the number of elements in the list <code class="code">l</code> - non tail recursive
</div>
</td></tr>
</table>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of types</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of types</h1>
<table>
</table>
</body>
</html>
+31
View File
@@ -0,0 +1,31 @@
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Index of values</title>
</head>
<body>
<div class="navbar">&nbsp;<a class="up" href="index.html" title="Index">Up</a>
&nbsp;</div>
<h1>Index of values</h1>
<table>
<tr><td align="left"><div>L</div></td></tr>
<tr><td><a href="Length.html#VALlength">length</a> [<a href="Length.html">Length</a>]</td>
<td></td></tr>
<tr><td><a href="Length.html#VALlength_tr">length_tr</a> [<a href="Length.html">Length</a>]</td>
<td><div class="info">
returns the number of elements in the list <code class="code">l</code> - tail recursive
</div>
</td></tr>
<tr><td align="left"><div>T</div></td></tr>
<tr><td><a href="Length.html#VALtest_length">test_length</a> [<a href="Length.html">Length</a>]</td>
<td></td></tr>
<tr><td><a href="Length.html#VALtest_length_tr">test_length_tr</a> [<a href="Length.html">Length</a>]</td>
<td></td></tr>
</table>
</body>
</html>
+43
View File
@@ -0,0 +1,43 @@
.keyword { font-weight : bold ; color : Red }
.keywordsign { color : #C04600 }
.comment { color : Green }
.constructor { color : Blue }
.type { color : #5C6585 }
.string { color : Maroon }
.warning { color : Red ; font-weight : bold }
.info { margin-left : 3em; margin-right: 3em }
.param_info { margin-top: 4px; margin-left : 3em; margin-right : 3em }
.code { color : #465F91 ; }
.typetable { border-style : hidden }
.paramstable { border-style : hidden ; padding: 5pt 5pt}
tr { background-color : White }
td.typefieldcomment { background-color : #FFFFFF ; font-size: smaller ;}
div.sig_block {margin-left: 2em}
*:target { background: yellow; }
body {font: 13px sans-serif; color: black; text-align: left; padding: 5px; margin: 0}
h1 { font-size : 20pt ; text-align: center; }
h2 { font-size : 20pt ; text-align: center; }
h3 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ;padding: 2px; }
h4 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90DDFF ;padding: 2px; }
h5 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90EDFF ;padding: 2px; }
h6 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90FDFF ;padding: 2px; }
div.h7 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ; padding: 2px; }
div.h8 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #E0FFFF ; padding: 2px; }
div.h9 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #F0FFFF ; padding: 2px; }
div.h10 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #FFFFFF ; padding: 2px; }
a {color: #416DFF; text-decoration: none}
a:hover {background-color: #ddd; text-decoration: underline}
pre { margin-bottom: 4px; font-family: monospace; }
pre.verbatim, pre.codepre { }
.indextable {border: 1px #ddd solid; border-collapse: collapse}
.indextable td, .indextable th {border: 1px #ddd solid; min-width: 80px}
.indextable td.module {background-color: #eee ; padding-left: 2px; padding-right: 2px}
.indextable td.module a {color: #4E6272; text-decoration: none; display: block; width: 100%}
.indextable td.module a:hover {text-decoration: underline; background-color: transparent}
.deprecated {color: #888; font-style: italic}
.indextable tr td div.info { margin-left: 2px; margin-right: 2px }
ul.indexlist { margin-left: 0; padding-left: 0;}
ul.indexlist li { list-style-type: none ; margin-left: 0; padding-left: 0; }
ul.info-attributes {list-style: none; margin: 0; padding: 0; }
div.info > p:first-child { margin-top:0; }
div.info-desc > p:first-child { margin-top:0; margin-bottom:0; }
+11
View File
@@ -0,0 +1,11 @@
<html><head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="Start" href="index.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Length" rel="Chapter" href="Length.html"><title>Length</title>
</head>
<body>
<code class="code"><span class="keyword">sig</span>&nbsp;<span class="keyword">end</span></code></body></html>
+187
View File
@@ -0,0 +1,187 @@
(*
if everything is fine, test functions
will return the unit value
*)
(** [length l] returns the number of elements in the list [l]; non tail recursive *)
let rec length l =
match l with
| [] -> 0
| x :: xs -> 1 + length xs;;
(**/**)
let test_length () =
assert (length [] = 0);
assert (length [2] = 1);
assert (length [5; 7; 8;] = 3)
(**/**)
(** [length_tr l] returns the number of elements in the list [l]; tail recursive *)
let length_tr l =
let rec lenth_tr' acc l =
match l with
| [] -> acc
| _ :: xs -> lenth_tr' (acc + 1) xs
in
lenth_tr' 0 l;;
(**/**)
let test_length_tr () =
assert (length_tr [] = 0);
assert (length_tr [2] = 1);
assert (length_tr [5; 7; 8;] = 3)
(**/**)
(** [reverse l] returns the reverse order of list [l]; non tail recursive *)
let rec reverse l =
match l with
| [] -> []
| x :: xs -> reverse xs @ [x];;
(**/**)
let test_reverse () =
assert (reverse [] = []);
assert (reverse [1] = [1]);
assert (reverse [1; 2] = [2; 1])
(**/**)
(** [reverse_tr l] returns the reverse order of list [l]; tail recursive *)
let reverse_tr l =
let rec reverse_tr' acc l =
match l with
| [] -> acc
| x :: xs -> reverse_tr' (x :: acc) xs
in
reverse_tr' [] l;;
(**/**)
let test_reverse_tr () =
assert (reverse_tr [] = []);
assert (reverse_tr [1] = [1]);
assert (reverse_tr [1; 2] = [2; 1])
(**/**)
(* list.rev is a built in reverse function *)
(** [take n l] returns a list containing the first [n] elements of [l];
* return [] if (n <= 0); return [l] if [l has fewer elements than [n]];
* non tail recursive *)
let rec take n l =
if n <= 0 then []
else
match l with
| [] -> []
| x :: xs -> x :: take (n - 1) xs
(**/**)
let test_take () =
assert (take 0 [1; 2; 3;] = []);
assert (take 3 [4; 5; 6; 7; 8; 9] = [4; 5; 6]);
assert (take 5 [1; 2; 3] = [1; 2; 3])
(**/**)
(** [take_tr n l] returns a list containing the first [n] elements of [l];
* return [] if (n <= 0); return [l] if [l has fewer elements than [n]];
* tail recursive *)
let take_tr n l =
let rec take_tr' acc n l =
if n <= 0 then reverse_tr(acc)
else
match l with
| [] -> acc
| x :: xs -> x :: take_tr' (x :: acc) (n - 1) xs
in
take_tr' [] n l;;
(**/**)
let test_take_tr () =
assert (take_tr 0 [1; 2; 3;] = []);
assert (take_tr 3 [4; 5; 6; 7; 8; 9] = [4; 5; 6]);
assert (take_tr 5 [1; 2; 3] = [1; 2; 3])
(**/**)
(** [every_other l] returns a list consisting of every other element of [l]
* starting from the first element; non tail recursive *)
let rec every_other l =
match l with
| x :: _ :: xs -> every_other xs
| _ -> l;;
(**/**)
let test_every_other () =
assert (every_other [] = []);
assert (every_other [1] = []);
assert (every_other [1; 2] = [2]);
assert (every_other [1; 2; 3] = [2]);
assert (every_other [1; 2; 3; 4] = [2; 4])
(**/**)
(** [every_other_tr l] returns a list consisting of every other element of [l]
* starting from the first element; tail recursive *)
let every_other_tr l =
let rec every_other_tr' acc l =
match l with
| x :: _ :: xs -> every_other_tr' (x :: acc) xs
| _ -> reverse_tr acc
in
every_other_tr' [] l;;
(**/**)
let test_every_other_tr () =
assert (every_other_tr [] = []);
assert (every_other_tr [1] = []);
assert (every_other_tr [1; 2] = [2]);
assert (every_other_tr [1; 2; 3] = [2]);
assert (every_other_tr [1; 2; 3; 4] = [2; 4])
(**/**)
(** [sum l1 l2] returns a list consisting of the sum of corresponding integers
* in [l1] and [l2]; non tail recursive *)
let rec sum l1 l2 =
match l1, l2 with (* this is a tuple of (l1, l2) *)
| [], _ | _, [] -> [] (* if l1 is empty or l2 is empty, return empty *)
| x1 :: xs1, x2 :: xs2 ->
(x1 + x2) :: sum xs1 xs2;;
(**/**)
let test_sum () =
assert (sum [] [] = []);
assert (sum [1] [] = []);
assert (sum [] [1] = []);
assert (sum [7] [8] = [15]);
assert (sum [7; 3] [8; 8] = [15; 11]);
assert (sum [7] [8; 8] = [15])
(**/**)
(** [sum_tr l1 l2] returns a list consisting of the sum of corresponding integers
* in [l1] and [l2]; tail recursive *)
let sum_tr l1 l2 =
let rec sum_tr' acc l1 l2 =
match l1, l2 with
| [], _ | _, [] -> reverse_tr acc
| x1 :: xs1, x2 :: xs2 ->
sum_tr' ((x1 + x2) :: acc) xs1 xs2
in
sum_tr' [] l1 l2;;
(**/**)
let test_sum_tr () =
assert (sum_tr [] [] = []);
assert (sum_tr [1] [] = []);
assert (sum_tr [] [1] = []);
assert (sum_tr [7] [8] = [15]);
assert (sum_tr [7; 3] [8; 8] = [15; 11]);
assert (sum_tr [7] [8; 8] = [15])
(**/**)
(** [count_change amt denoms] returns the number of ways of breaking up [amt]
* into currencies with denominations specified by [denoms];
* Require: elements of [denoms] must be positive *)
let rec count_change amt denoms =
if amt < 0 then 0
else if amt = 0 then 1
else
match denoms with
| [] -> 0
| d :: ds ->
count_change (amt - d) denoms + count_change amt ds;; (* use/not-use d *)
+135
View File
@@ -0,0 +1,135 @@
(*
***** TUPLES *****
has a fixed number of elements
*)
let x = (1, 2.1, "hello");;
(*
this is also a tuple, but this tuple
is a different type to the tuple above
*)
let y = (1, 2.1, "hello", "goodbye");;
(*
function with tuple argument
accepts a tuple with 3 elements of int
*)
let add_tuple (x, y, z) = x + y + z;;
(*
***** PATTERN MATCHING *****
where x gets deconstructed into a, b, and c
*)
let (a, b, c) = x;;
a;;
b;;
c;;
(*
***** LISTS *****
lists are semi-colon seperated values of the same type
lists are a recursive data type
*)
let nums = [1; 2; 3];; (* this is a valid list *)
(*
warning -
this is valid syntax but this is a list with a single
element that is a tuple of 3 ints
*)
let nums = [1, 2, 3];;
(* results in - list : [(1, 2, 3)] *)
(*
since lists are recursive data structures
we can add elements to the front of the list
as seen below
this operation is called cons
*)
2 :: (1 :: []);;
2 :: 1 :: [];;
(*
[1; 2; 3] === 1 :: 2 :: 3 :: [];;
*)
(* list of lists *)
[[1; 2]; [3; 4]];;
(* list concatonation *)
[1; 2] @ [3; 4];;
[];;
(*
results in - : 'a list = []
where 'a means its a type variable
since lists are generic
*)
let l = [[1; 2]; [3]; []];;
(*
pattern matching lists to extract 3
pattern matching must be exhaustive
*)
let [_; [x]; _] = l;;
let data = [(1, 2, 'a'); (5, 3, 'b'); (4, 1, 'c'); (5, 0, 'd')];;
let _ :: (_, _, x) :: _ = data;;
x;;
(*
recursive function
with pattern matching to find
length of list
*)
(**
* {length l} returns the number of elements
* in the list {l} - non tail recursive
*)
let rec length l =
match l with
| [] -> 0
| x :: xs -> 1 + length xs;;
(**
* {length_tr l} returns the number of elements
* in the list {l} - tail recursive
*)
let length_tr l =
let rec aux acc l =
match l with
| [] -> acc
| _ :: xs -> aux (acc + 1) xs
in
aux 0 l;;
(*
GENERATE WEB DOCUMENTATION
mkdir html
ocamldoc -html -d html main.ml
*)
(*
there is no void in ocaml,
everything has to return a value
all expressions have a value;
if your function has no value to
return, you still need to return something
so return the unit value
example:
printf is like a utility to print to the
console but does not need to return any value
so it returns the unit value
*)
Printf.printf "Hello, world\n";;
+214
View File
@@ -0,0 +1,214 @@
(* PARTIAL FUNCTIONS - because it does not return a value in
some cases *)
let hd l =
match l with
| [] -> failwith "hd: empty list"
| x:: _ -> x;;
let tl l =
match l with
| [] -> failwith "tl: empty list"
| _ :: xs -> xs;;
(* associative list is a list of pairs *)
let al = [("a123", 55); ("b456", 67)];;
(** [find k l] returns a value v from a key [k] in a list of pairs [l]
* fails if not found
*)
let rec find k l =
match l with
| [] -> failwith "find: key not found"
| (k', v') :: _ when k = k' -> v'
| _ :: xs -> find k xs;;
(*
best case is to have a TOTAL FUNCTION, always return a value
this can be accomplished with an option type, that has two
variants, either None or Some e.g. None;; Some 2;;
*)
(** [find_opt k l] returns an optional value v from a key [k] in a list of pairs [l] *)
let rec find_opt k l =
match l with
| [] -> None
| (k', v') :: _ when k = k' -> Some v'
| _ :: xs -> find_opt k xs;;
(*** HIGHER ORDER FUNCTIONS ***)
(** [insert x l] inserts element [x] into list [l]
* Requires: [l] is in ascending order. *)
let rec insert x l =
match l with
| [] -> [x]
| y :: ys ->
if x <= y then x :: l
else y :: insert x ys;;
(* Note: the following insert is the same logically, just shorter *)
(** [insert x l] inserts element [x] into list [l]
* Requires: [l] is in ascending order. *)
let rec insert x l =
match l with
| y :: ys when x > y -> y :: insert x ys
| _ -> x :: l
(** [insertion_sort l] sorts list [l] in ascending order *)
let rec insertion_sort l =
match l with
| [] -> []
| x :: xs -> insert x (insertion_sort xs)
(*** ANONYMOUS FUNCTIONS ***)
(* fun x -> x * x;; <-- syntax*)
let f' x = x * x;;
(* these functions are equivalent *)
let a = fun x y -> x + y;; (* func that takes two params *)
let a' x = fun y -> x + y;; (* func taht takes 1 param and returns a func that takes 1 param *)
let s x = x * x;;
(* f 2 + 3;; (* result: 7 *)
f (2 + 3);; (* result: 25 *)
f @@ 2 + 3;; (* result: 25 *) *)
let rec insertion_sort l =
match l with
| [] -> []
| x :: xs -> insert x @@ insertion_sort xs;;
(* function is short form of "l = match l with ..." *)
let rec insertion_sort = function
| [] -> []
| x :: xs -> insert x @@ insertion_sort xs;;
let inc x = x + 1;;
let square x = x * x;;
let add x y = x + y;;
square (inc 1);; (* r = 4 *)
square @@ inc 1;; (* r = 4 *)
1 |> inc |> square;; (* pipe operator - r = 4 or <|*)
1 |> inc |> square |> add 2;; (* r = 6 *)
let flip f x y = f y x;;
let sub x y = x - y;;
flip sub 1 2;; (* flips two arguments, becomes sub 2 1 *)
(** [map f l] for each element in list [l] apply func [f]
* return list of [l] with func [f] applied to elems *)
let rec map f l =
match l with
| [] -> []
| x :: xs -> f x :: map f xs;;
map (fun x -> x * x) [1; 2; 3; 4; 5; 6];;
map int_of_string_opt ["1"; "2"; "3"; "z"];;
(** [filter f l] for each element in list [l] keep
* element if it passes predicate func [f] *)
let rec filter f l =
match l with
| [] -> []
| x :: xs when f x -> x :: filter f xs
| _ :: xs -> filter f xs;;
filter (fun x -> x mod 2 = 0) [1; 2; 3; 4; 5; 6; 7; 8; 9];;
["a"; "1"; "2"] |> map int_of_string_opt |> filter (function | None -> false | Some _ -> true) (* filter out None *)
(* list gets piped into the snd arg of map and result of map is piped to snd arg of filter *)
(* pipes can go left also? <| *)
(** [take_while f l] returns the longest prefix of [l] each of its elements
* satisfying [f] *)
let take_while f l =
let rec aux l acc =
match l with
| [] -> List.rev acc
| x :: xs ->
if f x then aux xs (x :: acc)
else List.rev acc
in
aux l [];;
take_while (fun x -> x mod 2 = 0) [3; 2; 6; 6; 8];;
take_while (fun x -> x mod 2 = 0) [2; 6; 7; 6; 8];;
take_while (fun x -> x mod 2 = 0) [2; 6; 6; 8];;
(** [take_while f l] returns the longest prefix of [l] each of its elements
* satisfying [f] *)
let take_while f l =
let rec aux l acc =
match l with
| x :: xs when f x -> aux xs (x :: acc)
| _ -> List.rev acc
in
aux l [];;
take_while (fun x -> x mod 2 = 0) [3; 2; 6; 6; 8];;
take_while (fun x -> x mod 2 = 0) [2; 6; 7; 6; 8];;
take_while (fun x -> x mod 2 = 0) [2; 6; 6; 8];;
(*
cmp x y < 0 x before y
= 0 doesnt matter, x = y
> 0 x after y
*)
let rec insert' cmp x l =
match l with
| [] -> [x]
| y :: ys ->
if cmp x y <= 0 then x :: l
else y :: insert' cmp x ys;;
let rec sort' cmp l =
match l with
| [] -> []
| x :: xs ->
insert' cmp x @@ sort' cmp xs;;
sort' Int.compare [3;2;7;6;8];;
sort' (Fun.flip Int.compare) [3;2;7;6;8];;
(* with labeled arguments *)
let rec insert'' ~cmp x l =
match l with
| [] -> [x]
| y :: ys ->
if cmp x y <= 0 then x :: l
else y :: insert'' ~cmp x ys;;
let rec sort'' ~cmp l =
match l with
| [] -> []
| x :: xs ->
insert'' ~cmp x @@ sort'' ~cmp xs;;
(* labeled arguments can go anywhere *)
sort'' [3;2;7;6;8] ~cmp:Int.compare;;
sort'' ~cmp:(Fun.flip Int.compare) [3;2;7;6;8];;
(* process list from left to right *)
(* fold_left -> (((acc $ x1) $ x2) $ x3) *)
let rec fold_left f acc l =
match l with
| [] -> acc
| x :: xs -> fold_left f (f acc x) xs;;
fold_left (fun acc x -> acc + x) 0 [3; 2; 7; 6; 8];;
fold_left (+) 0 [3; 2; 7; 6; 8];;
(+) 1 3;; (* makes + act like a function *)
(* process list from right to left *)
(* fold_right -> (x1 $ (x2 $ (x3 $ acc))) *)
let rec fold_right f l acc =
match l with
| [] -> acc
| x :: xs -> f x (fold_right f xs acc);;
fold_left min max_int [3; 2; 7; 6; 8];;
fold_right min [3; 2; 7; 6; 8] max_int;;
+65
View File
@@ -0,0 +1,65 @@
type 'a bstree = Leaf | Node of 'a * 'a bstree * 'a bstree;;
let rec bstree_size t =
match t with
| Leaf -> 0
| Node (_, l, r) ->
1 + bstree_size l + bstree_size r;;
let rec bstree_height t =
match t with
| Leaf -> 0
| Node (_, l, r) ->
1 + max (bstree_height l) (bstree_height r);;
let bstree_empty = Leaf;;
let bstree_is_empty t = t = Leaf;;
let rec bstree_insert ~cmp x t =
match t with
| Leaf -> Node (x, Leaf, Leaf)
| Node (x', l, r) when cmp x x' < 0 ->
Node (x', bstree_insert ~cmp x l, r)
| Node (x', l, r) when cmp x x' > 0 ->
Node (x', l, bstree_insert ~cmp x r)
| _ -> t;;
let bstree_of_list ~cmp l =
List.fold_left (Fun.flip (bstree_insert ~cmp)) Leaf l;;
let rec bstree_mem ~cmp x t =
match t with
| Leaf -> false
| Node (x', l, _) when cmp x x' < 0 ->
bstree_mem ~cmp x l
| Node (x', _, r) when cmp x x' > 0 ->
bstree_mem ~cmp x r
| _ -> true;;
let rec bstree_largest t =
match t with
| Leaf -> failwith "bstree_largest: empty tree"
| Node (x, _, Leaf) -> x
| Node (_, _, r) -> bstree_largest r;;
let rec bstree_smallest t =
match t with
| Leaf -> failwith "bstree_smallest: empty tree"
| Node (x, Leaf, _) -> x
| Node (_, l, _) -> bstree_smallest l;;
let rec bstree_delete ~cmp x t =
match t with
| Leaf -> Leaf
| Node (x', l, r) when cmp x x' < 0 ->
Node (x', bstree_delete ~cmp x l, r)
| Node (x', l, r) when cmp x x' > 0 ->
Node (x', l, bstree_delete ~cmp x r)
| Node (_, Leaf, Leaf) -> Leaf (* this does not need to be here, its a special case but ill leave it for clarity *)
| Node (_, l, Leaf) -> l
| Node (_, Leaf, r) -> r
| Node (_, l, r) ->
let succ = bstree_largest l in
Node (succ, bstree_delete ~cmp succ l, r);;
+10
View File
@@ -0,0 +1,10 @@
type bstree_size : 'a bstree -> int
val bstree_height : 'a bstree -> int
val bstree_empty : 'a bstree
val bstree_is_empty : 'a bstree -> bool
val bstree_insert : cmp:('a -> 'a -> int) -> 'a -> 'a bstree -> 'a bstree
val bstree_of_list : cmp:('a -> 'a -> int) -> 'a list -> 'a bstree
val bstree_mem : cmp:('a -> 'b -> int) -> 'a -> 'b bstree -> bool
val bstree_largest : 'a bstree -> 'a
val bstree_smallest : 'a bstree -> 'a
val bstree_delete : cmp:('a -> 'a -> int) -> 'a -> 'a bstree -> 'a bstree
+107
View File
@@ -0,0 +1,107 @@
(* Some, None - Are called data/value constructors *)
Some 1;; (* - : int option = Some 1 *)
None;; (* - : 'a option = None *)
(* OPTIONS are called type constructors, it takes a type *)
(* 'a is a type variable, where 'a is some type such as int *)
type 'a option = None | Some of 'a;;
(*
You can define any type you want, this type constructor starts
with a lower case letter "direction" and the value constructor starts
with uppercase "North", "East", ...
type constructors are not functions
*)
type direction = North | East | South | West;;
(* There are RESULT types *)
Ok 1;;
Error "hell";; (* albert's example is hell not my example *)
(*
A result is a two type variable, this is the syntax for
something that takes to type variables
*)
type ('a, 'b) result = Ok of 'a | Error of 'b;;
(1, 2);; (* type is - : int * int = (1, 2) *)
(* (int, int) : (type * type) *)
(* we define an expresion that has a type of Int, and can be of type Add, Sub or Mul *)
type expr =
Int of int
| Add of expr * expr
| Sub of expr * expr
| Mul of expr * expr;;
(* We then define an eval function, that takes in an eval,
and recursively evaluates e1, e2 till they are just of
type Int to then evaluate the addition, subtraction, etc. *)
let rec eval = function
| Int n -> n
| Add (e1, e2) -> eval e1 + eval e2
| Sub (e1, e2) -> eval e1 - eval e2
| Mul (e1, e2) -> eval e1 * eval e2;;
let e = Mul(Add (Int 1, Int 2), Int 7);;
eval e;;
(* lets apply the type variables and constructors to create a card type *)
type suit = Club | Diamond | Heart | Spade;;
type rank = Num of int | Jack | Queen | King | Ace;;
type card = rank * suit;;
let compare_rank r1 r2 =
match r1, r2 with
| Num x, Num y -> Int.compare x y
| Num _, _ -> -1
| _, Num _ -> 1
| _, _ -> Stdlib.compare r1 r2;;
let compare_suit s1 s2 = Stdlib.compare s1 s2;;
let compare_card (r1, s1) (r2, s2) =
let c = compare_rank r1 r2 in
if c = 0 then compare_suit s1 s2
else c;;
let string_of_suit = function
| Club -> "clubs"
| Diamond -> "diamonds"
| Heart -> "hearts"
| Spade -> "spades";;
let string_of_rank = function
| Num n -> string_of_int n
| Jack -> "Jack"
| Queen -> "Queen"
| King -> "King"
| Ace -> "Ace"
let string_of_card (r, s) =
string_of_rank r ^ " of " ^ string_of_suit s;;
compare_card (King, Diamond) (Queen, Heart);;
string_of_card (Queen, Heart);;
let all_suits = [Club; Diamond; Heart; Spade];;
let all_ranks =
(List.init 9 (fun x -> x + 2) |> List.map (fun x -> Num x)) @
[Jack; Queen; King; Ace];;
let all_cards =
List.fold_right (fun rank acc -> (
List.fold_right (fun suit acc -> (rank, suit) :: acc) all_suits []
) @ acc) all_ranks [];;
type 'a linked_list = Nil | Cons of 'a * 'a linked_list;;
let rec map_linked f = function
| Nil -> Nil
| Cons (x, l) -> Cons (f x, map_linked f l);;
Cons (1, Cons (2, Cons (3, Nil))) |> map_linked (fun x -> x * x);;
+25
View File
@@ -0,0 +1,25 @@
"Resource: /home/flami/Projects/comp3958/lecture05/number_lines.ml": "n\239\025\\<\011\028#\000A>\249\204\182\170r"
"Rule: ocaml dependencies ml (%=cat )": "\210V\221`\251\191B\198\232\184\146#\164\015\176,"
"Rule: ocaml: cmx* & o* -> native (%=number_file_lines )": "R|\021U[G\226zs:\214\154\1910a\177"
"Rule: ocaml: ml & cmi -> cmx & o (%=cat )": "\025\244\2354\235@{lBk\211\031$\237><"
"Rule: ocaml: cmx* & o* -> native (%=number_lines )": "\180K\170\211^n:g\196\220\030 \233\127*\149"
"Rule: ocaml: cmx* & o* -> native (%=echo )": "\196\206\211\186\185&f\154\217p\215\195\248p\1485"
"Resource: /home/flami/Projects/comp3958/lecture05/echo.ml": "h\001\167\215xe\171\150p\151\004p>\004%\181"
"Rule: ocaml dependencies ml (%=sum_integers )": "\207\140\220\182.\186\127\200\228\226\152\002dAJ\134"
"Rule: ocaml dependencies ml (%=echo )": "\237\219\161\187\134\217\180\030\148\240\0166\176W\2222"
"Resource: /home/flami/Projects/comp3958/lecture05/sum_integers.ml": "#b[\196\162u!\202\205~\135\239\025i\195\215"
"Rule: ocaml: ml -> cmo & cmi (%=sum_integers )": "\015x\165\015\217\024\189(\143ud\232#\158Um"
"Rule: ocaml: cmx* & o* -> native (%=sum_integers )": "q.\011\170\190\228da(\218\172\231\192\136\236+"
"Rule: ocaml: ml -> cmo & cmi (%=cat )": "\248U3\213\015A\001\180 \023\180>\223}\142\188"
"Rule: ocaml: ml -> cmo & cmi (%=number_file_lines )": "\218\210>\023\150\016u\174\235\179&6\234\147\248\016"
"Rule: ocaml: ml & cmi -> cmx & o (%=echo )": "\1770\n\142p\235j\205HX\163\208\005\133n\t"
"Rule: ocaml: ml & cmi -> cmx & o (%=sum_integers )": "\024\022\151\178THu\229\251\017\175G\230\179rD"
"Rule: ocaml dependencies ml (%=number_lines )": "\023O8\158;\213,z\t`\236\204\250\168\140W"
"Resource: /home/flami/Projects/comp3958/lecture05/number_file_lines.ml": ":\233\133ai\245 \000\199f8\022\140<\199\174"
"Resource: /home/flami/Projects/comp3958/lecture05/cat.ml": "^\135\t\199Rr\210]\197\127HpY\r\147\170"
"Rule: ocaml: ml -> cmo & cmi (%=echo )": "\224\\C\014\150\004=\191p\132*-\017jj\242"
"Rule: ocaml dependencies ml (%=number_file_lines )": "\142\151\154\251\184\227\201\196\243\150\003\242\017\222\229X"
"Rule: ocaml: ml & cmi -> cmx & o (%=number_lines )": "l\154\251\180\134\026\206s\139\030!A\155\t\198\161"
"Rule: ocaml: ml -> cmo & cmi (%=number_lines )": "\029\1849 z\004\n\025\253\155]\017\244\252\141\129"
"Rule: ocaml: cmx* & o* -> native (%=cat )": "j\019\018\218,\202\215\161 &5SE\134\223/"
"Rule: ocaml: ml & cmi -> cmx & o (%=number_file_lines )": "|\132>\000@\222\195L,\1271\1424\141wJ"
+12
View File
@@ -0,0 +1,12 @@
### Starting build.
# Target: /home/flami/.opam/default/bin/ocamlc.opt -config, tags: { }
/home/flami/.opam/default/bin/ocamlc.opt -config
# Target: number_lines.ml.depends, tags: { extension:ml, file:number_lines.ml, ocaml, ocamldep, quiet }
/home/flami/.opam/default/bin/ocamldep.opt -modules number_lines.ml > number_lines.ml.depends
# Target: number_lines.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:number_lines.cmo, file:number_lines.ml, implem, ocaml, quiet }
/home/flami/.opam/default/bin/ocamlc.opt -c -o number_lines.cmo number_lines.ml
# Target: number_lines.cmx, tags: { compile, extension:cmx, extension:ml, file:number_lines.cmx, file:number_lines.ml, implem, native, ocaml, quiet }
/home/flami/.opam/default/bin/ocamlopt.opt -c -o number_lines.cmx number_lines.ml
# Target: number_lines.native, tags: { dont_link_with, extension:native, file:number_lines.native, link, native, ocaml, program, quiet }
/home/flami/.opam/default/bin/ocamlopt.opt number_lines.cmx -o number_lines.native
# Compilation successful.
Binary file not shown.
+25
View File
@@ -0,0 +1,25 @@
(* display content of file read via stdin *)
let rec cat () =
try
let line = read_line () in
print_endline line;
cat()
with
| _ -> ();; (* EOF return unit *)
(* similar to main function *)
let () =
let rec aux () =
try
print_endline @@ read_line ();
aux ()
with
| _ -> ()
in
aux()
(**** build and test ****)
(*
ocamlbuild cat.native
./cat.native < filename
*)
+1
View File
@@ -0,0 +1 @@
cat.ml:
Binary file not shown.
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
let () =
let len = Array.length Sys.argv - 1 in
for i = 1 to len do
Printf.printf (if i <> len then "%s " else "%s\n") Sys.argv.(i)
done;;
+1
View File
@@ -0,0 +1 @@
echo.ml: Array Printf Sys
Binary file not shown.
Binary file not shown.
+16
View File
@@ -0,0 +1,16 @@
let rec number acc ic =
try
Printf.printf "%5d| %s\n" acc @@ input_line ic;
number (acc + 1) ic
with
| _ -> if ic <> stdin then close_in ic else ()
let () =
if Array.length Sys.argv = 1 then
number 1 stdin
else
try
number 1 @@ open_in Sys.argv.(1)
with
| Sys_error s -> Printf.eprintf "%s\n" s;;
@@ -0,0 +1 @@
number_file_lines.ml: Array Printf Sys
Binary file not shown.
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
let () =
let rec aux acc =
try
Printf.printf "%5d| %s\n" acc @@ read_line ();
aux (acc + 1)
with
| _ -> ()
in
aux 1;;
@@ -0,0 +1 @@
number_lines.ml: Printf
Binary file not shown.
Binary file not shown.
+12
View File
@@ -0,0 +1,12 @@
let () =
let rec aux sum =
try
aux @@ Scanf.scanf " %d" (fun x -> sum + x)
with
| Scanf.Scan_failure _ ->
Scanf.scanf " %s" (fun _ -> ());
aux sum
| End_of_file -> sum
in
Printf.printf "%d\n" @@ aux 0;;
@@ -0,0 +1 @@
sum_integers.ml: Printf Scanf
Binary file not shown.
+26
View File
@@ -0,0 +1,26 @@
(* display content of file read via stdin *)
let rec cat () =
try
let line = read_line () in
print_endline line;
cat()
with
| _ -> ();; (* EOF return unit *)
(* similar to main function *)
let () =
let rec aux () =
try
print_endline @@ read_line ();
aux ()
with
| _ -> ()
in
aux()
(* cat() *)
(**** build and test ****)
(*
ocamlbuild cat.native
./cat.native < filename
*)
+4
View File
@@ -0,0 +1,4 @@
123 456
-123 -456
abc
25
+6
View File
@@ -0,0 +1,6 @@
let () =
let len = Array.length Sys.argv - 1 in
for i = 1 to len do
Printf.printf (if i <> len then "%s " else "%s\n") Sys.argv.(i)
done;;
+160
View File
@@ -0,0 +1,160 @@
(**** RECORDS ****)
type student = {id: string; name: string; gpa: float};;
let s1 = {id = "a12345678"; name = "homer simpson"; gpa = 25.5};;
let make_student id name gpa = { id = id; name = name; gpa = gpa };;
let s2 = make_student "a000000" "monty burns" 99.9;;
(* defining a function to return the name field of a record *)
let name {id = id; name = name; gpa = gpa} = name;;
let name {id; name; gpa} = name;;
let name {name} = name;;
let name s = s.name;;
name s2;;
type instructor = {id: string; name: string; salary: float};;
let i1 = {id = "a777777"; name = "lisa simpson"; salary = 100000.};;
(* name cannot be applied to constructor because name was defined before instructor
and it deferred from student *)
(* name i1;; *)
let id x = x.id;;
(* id s1;; <-- this doesnt work because id infers from the latest defined, such as instructor *)
id i1;;
type isntr = Instructor of {id: string; name: string; salary: float};;
let i1 = Instructor {id = "a777777"; name = "lisa simpson"; salary = 100000.};;
let s1 = make_student "a123456678" "homer simpson" 25.5;;
let s2 = s1;; (* s2 is its own student it just shares the same data *)
let s2 = {s1 with id = "a22222222"; name = "bart simpson"} (* this allows us to copy data and modify selected data *)
(**** MUTABILITY - you can mark fields as mutable ****)
type student = {id: string; name: string; mutable gpa: float};;
let make_student id name gpa = { id = id; name = name; gpa = gpa };;
let s1 = make_student "a123456678" "homer simpson" 25.5;;
let s2 = s1;; (* refer to the same thing *)
s2;;
(* update field for s1 *)
s1.gpa <- 15.5;
(* shows changes applied to s1 since s2 refers to the same data *)
s2;;
(**** REFERENCES & DEREFEREMCES ****)
let x = ref 1;;
!x;; (* deref *)
x := 2;; (* update val of references *)
x;;
!x;;
let y = x;;
y;;
x;;
incr x;; (* y is the same as x (ref to int) so updating x also shows in y *)
x;;
y;;
let x = ref (Some 1);;
let y = ref None;;
(* val y : '_wek1 option ref = {contents = None} *)
(* curremtly the contents of y are weakly polymorphic
because it can be any type. the type inference cannot
deduce the value of the optional *)
y := Some 2;;
y;;
(* - : int option ref = {contents = Some 1} *)
(**** ARRAYS - arrays are mutable ****)
[|1;2;3;3;4;5|];; (* arrays have vertical bars unlike lists *)
let a = [|1;2;3|];;
a.(0);; (* get first element *);;
a.(1);;
a.(2);;
(* a.(3);; (* Invalid_argument excetption *) *)
a.(0) <- -1;;
a;;
(**** FOR / WHILE LOOPS ****)
(* for loops on arrays... yikes *)
Array.length a;;
for i = 0 to Array.length a - 1 do
a.(i) <- 2 * a.(i)
done;;
a;;
(* you can go in reverse also using downto *)
for i = Array.length a - 1 downto 0 do
a.(i) <- 2 * a.(i)
done;;
(* while loops also... *)
let i = ref 0;;
while !i < Array.length a do
(* adding semi-colon to end of expression means
this is a garbage value, throw it away so we
dont return unit() type early *)
a.(!i) <- - !i;
incr i
done;;
a;;
(**** IGNORE ****)
(* x will be 2 and the expression 1;
is ignored because of the semi-colon *)
let x = ignore 1; 2;;
(**** EXCEPTIONS ****)
(* defining exceptions and rasing *)
(* exception is a variant type and the
number of variants can be extended *)
(* exception Hell;; *)
(* raise Hell;;
Failure "hell";; *)
(* exceptions can have parameters *)
exception Hell of int;;
Hell 1;;
Hell 2;;
(* List.hd [];; (* raises an exception *) *)
(* you can pattern match exceptions with try-with *)
try
List.hd []
with
| Failure _ -> -1;;
try
List.hd []
with
| _ -> -1;;
(**** IO ****)
print_string "hello world\n";;
print_endline "hello world";;
print_int 123;;
print_float 123.4;;
print_newline ();;
Printf.printf "%5d\n" 123;;
Printf.printf "%05d %s\n" 123 "hello";;
Printf.eprintf "%05d %s\n" 123 "hello";; (* print to standard error channel *)
let x = read_line ();;
(* read in int - add space at the front, it matches any amount of leading whitespace *)
Scanf.scanf " %d" (fun x -> x)
(* open file *)
(* open_in "filename";; *)
let ic = open_in "output";;
input_line ic;;
+16
View File
@@ -0,0 +1,16 @@
let rec number acc ic =
try
Printf.printf "%5d| %s\n" acc @@ input_line ic;
number (acc + 1) ic
with
| _ -> if ic <> stdin then close_in ic else ()
let () =
if Array.length Sys.argv = 1 then
number 1 stdin
else
try
number 1 @@ open_in Sys.argv.(1)
with
| Sys_error s -> Printf.eprintf "%s\n" s;;
+9
View File
@@ -0,0 +1,9 @@
let () =
let rec aux acc =
try
Printf.printf "%5d| %s\n" acc @@ read_line ();
aux (acc + 1)
with
| _ -> ()
in
aux 1;;
+1
View File
@@ -0,0 +1 @@
hello world
+12
View File
@@ -0,0 +1,12 @@
(* we can impliment our own ref type *)
type 'a ref = { mutable contents: 'a };;
(* reference and dereference implimentation *)
let ref x = { contents = x };;
let (!) r = r.contents;;
(* assign to a mutable field *)
let (:=) r x = r.contents <- x;;
let incr r = r.contents <- r.contents + 1;;
let decr r = r.contents <- r.contents - 1;;
+12
View File
@@ -0,0 +1,12 @@
let () =
let rec aux sum =
try
aux @@ Scanf.scanf " %d" (fun x -> sum + x)
with
| Scanf.Scan_failure _ ->
Scanf.scanf " %s" (fun _ -> ());
aux sum
| End_of_file -> sum
in
Printf.printf "%d\n" @@ aux 0;;
+3
View File
@@ -0,0 +1,3 @@
"Rule: ocaml dependencies ml (%=two_list_queue )": "\153s\252\225.\205\197\1597\030\142\254Q\213.\135"
"Resource: /home/flami/Projects/comp3958/lecture06/two_list_queue.ml": "\174\189*\255(\166==\251\006\232\150\141\1714\130"
"Rule: ocaml: ml -> cmo & cmi (%=two_list_queue )": "9\165\179\031F'#6\127\149\136<\242y\019t"
+8
View File
@@ -0,0 +1,8 @@
### Starting build.
# Target: /home/flami/.opam/default/bin/ocamlc.opt -config, tags: { }
/home/flami/.opam/default/bin/ocamlc.opt -config
# Target: two_list_queue.ml.depends, tags: { extension:ml, file:two_list_queue.ml, ocaml, ocamldep, quiet }
/home/flami/.opam/default/bin/ocamldep.opt -modules two_list_queue.ml > two_list_queue.ml.depends
# Target: two_list_queue.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:two_list_queue.cmo, file:two_list_queue.ml, implem, ocaml, quiet }
/home/flami/.opam/default/bin/ocamlc.opt -c -o two_list_queue.cmo two_list_queue.ml
# Compilation successful.
+42
View File
@@ -0,0 +1,42 @@
(* queue is empty iff the first list is empty *)
type 'a t = 'a list * 'a list;;
exception Empty;;
let empty = ([], []);;
let is_empty (l, _) = l = [];;
let enqueue x (l1, l2) =
match l1 with
| [] -> [x], l2
| _ -> (l1, x :: l2);;
let dequeue (l1, l2) =
match l1 with
| [] -> raise Empty
| [_] -> (List.rev l2, [])
| _ :: xs -> (xs, l2);;
let dequeue_opt q =
try
Some (dequeue q)
with
| Empty -> None;;
let front (l, _) =
match l with
| [] -> raise Empty
| x :: _ -> x;;
let front_opt (l, _) =
match l with
| [] -> None
| x :: _ -> Some x;;
let of_list l =
List.fold_left (Fun.flip enqueue) empty l;;
let to_list (l1, l2) =
l1 @ List.rev l2;;
@@ -0,0 +1 @@
two_list_queue.ml: Fun List
+63
View File
@@ -0,0 +1,63 @@
type 'a t = Leaf | Node of 'a * 'a t * 'a t;;
let rec size t =
match t with
| Leaf -> 0
| Node (_, l, r) ->
1 + size l + size r;;
let rec height t =
match t with
| Leaf -> 0
| Node (_, l, r) ->
1 + max (height l) (height r);;
let empty = Leaf;;
let is_empty t = t = Leaf;;
let rec insert x t =
match t with
| Leaf -> Node (x, Leaf, Leaf)
| Node (x', l, r) when x < x' ->
Node (x', insert x l, r)
| Node (x', l, r) when x > x' ->
Node (x', l, insert x r)
| _ -> t;;
let of_list l =
List.fold_left (Fun.flip insert) Leaf l;;
let rec mem x t =
match t with
| Leaf -> false
| Node (x', l, _) when x < x' ->
mem x l
| Node (x', _, r) when x > x' ->
mem x r
| _ -> true;;
let rec largest t =
match t with
| Leaf -> failwith "largest: empty tree"
| Node (x, _, Leaf) -> x
| Node (_, _, r) -> largest r;;
let rec smallest t =
match t with
| Leaf -> failwith "smallest: empty tree"
| Node (x, Leaf, _) -> x
| Node (_, l, _) -> smallest l;;
let rec delete x t =
match t with
| Leaf -> Leaf
| Node (x', l, r) when x < x' ->
Node (x', delete x l, r)
| Node (x', l, r) when x > x' ->
Node (x', l, delete x r)
| Node (_, l, Leaf) -> l
| Node (_, Leaf, r) -> r
| Node (_, l, r) ->
let succ = largest l in
Node (succ, delete succ l, r);;
+14
View File
@@ -0,0 +1,14 @@
(* type 'a t = Leaf | Node of 'a * 'a t * 'a t *)
type 'a t (* for abstract data type *)
val size : 'a t -> int
val height : 'a t -> int
val empty : 'a t
val is_empty : 'a t -> bool
val insert : 'a -> 'a t -> 'a t
val of_list : 'a list -> 'a t
val mem : 'a -> 'a t -> bool
val largest : 'a t -> 'a
val smallest : 'a t -> 'a
val delete : 'a -> 'a t -> 'a t
+68
View File
@@ -0,0 +1,68 @@
(* dont do this *)
module Bstree = struct
type 'a t = Leaf | Node of 'a * 'a t * 'a t;;
let rec size t =
match t with
| Leaf -> 0
| Node (_, l, r) ->
1 + size l + size r;;
let rec height t =
match t with
| Leaf -> 0
| Node (_, l, r) ->
1 + max (height l) (height r);;
let empty = Leaf;;
let is_empty t = t = Leaf;;
let rec insert x t =
match t with
| Leaf -> Node (x, Leaf, Leaf)
| Node (x', l, r) when x < x' ->
Node (x', insert x l, r)
| Node (x', l, r) when x > x' ->
Node (x', l, insert x r)
| _ -> t;;
let of_list l =
List.fold_left (Fun.flip insert) Leaf l;;
let rec mem x t =
match t with
| Leaf -> false
| Node (x', l, _) when x < x' ->
mem x l
| Node (x', _, r) when x > x' ->
mem x r
| _ -> true;;
let rec largest t =
match t with
| Leaf -> failwith "largest: empty tree"
| Node (x, _, Leaf) -> x
| Node (_, _, r) -> largest r;;
let rec smallest t =
match t with
| Leaf -> failwith "smallest: empty tree"
| Node (x, Leaf, _) -> x
| Node (_, l, _) -> smallest l;;
let rec delete x t =
match t with
| Leaf -> Leaf
| Node (x', l, r) when x < x' ->
Node (x', delete x l, r)
| Node (x', l, r) when x > x' ->
Node (x', l, delete x r)
| Node (_, l, Leaf) -> l
| Node (_, Leaf, r) -> r
| Node (_, l, r) ->
let succ = largest l in
Node (succ, delete succ l, r);;
end
+6
View File
@@ -0,0 +1,6 @@
"Rule: ocaml dependencies mli (%=bstree )": "!\134$\216+23\213\196T\181K\021\128\195\018"
"Resource: /home/flami/Projects/comp3958/lecture06/functor/bstree.mli": "\194\172\208\246\172^Y\171\1563@\144\158H\027l"
"Rule: ocaml: ml & cmi -> cmo (%=bstree )": "\172\028\140\193\160\2525\162\225\231@cE\2307\244"
"Resource: /home/flami/Projects/comp3958/lecture06/functor/bstree.ml": "\228\211>\161\t\1291\180\144c_ \189\147\236x"
"Rule: ocaml: mli -> cmi (%=bstree )": "\225aH6\244\021+9l\172\247\209 d\183\159"
"Rule: ocaml dependencies ml (%=bstree )": "\031$\199\007@\208\227\1694l\138\193r\227\203\171"
+12
View File
@@ -0,0 +1,12 @@
### Starting build.
# Target: /home/flami/.opam/default/bin/ocamlc.opt -config, tags: { }
/home/flami/.opam/default/bin/ocamlc.opt -config
# Target: bstree.mli.depends, tags: { extension:mli, file:bstree.mli, ocaml, ocamldep, quiet }
/home/flami/.opam/default/bin/ocamldep.opt -modules bstree.mli > bstree.mli.depends # cached
# Target: bstree.cmi, tags: { byte, compile, extension:mli, file:bstree.mli, interf, ocaml, quiet }
/home/flami/.opam/default/bin/ocamlc.opt -c -o bstree.cmi bstree.mli # cached
# Target: bstree.ml.depends, tags: { extension:ml, file:bstree.ml, ocaml, ocamldep, quiet }
/home/flami/.opam/default/bin/ocamldep.opt -modules bstree.ml > bstree.ml.depends
# Target: bstree.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:bstree.cmo, file:bstree.ml, implem, ocaml, quiet }
/home/flami/.opam/default/bin/ocamlc.opt -c -o bstree.cmo bstree.ml
# Compilation successful.
+86
View File
@@ -0,0 +1,86 @@
module type OrderedType = sig
type t
val compare : t -> t -> int
end
module type S = sig
type elt
type t
val size : t -> int
val height : t -> int
val empty : t
val is_empty : t -> bool
val insert : elt -> t -> t
val of_list : elt list -> t
val mem : elt -> t -> bool
val delete : elt -> t -> t
end
module Make(Ord : OrderedType) = struct
type elt = Ord.t;;
type t = L | N of elt * t * t;;
let rec size t =
match t with
| L -> 0
| N (_, l, r) ->
1 + size l + size r;;
let rec height t =
match t with
| L -> 0
| N (_, l, r) ->
1 + max (height l) (height r);;
let empty = L;;
let is_empty t = t = L;;
let rec insert x t =
match t with
| L -> N (x, L, L)
| N (x', l, r) when Ord.compare x x' < 0 ->
N (x', insert x l, r)
| N (x', l, r) when Ord.compare x x' > 0 ->
N (x', l, insert x r)
| _ -> t;;
let of_list l =
List.fold_left (Fun.flip insert) L l;;
let rec mem x t =
match t with
| L -> false
| N (x', l, _) when Ord.compare x x' < 0 ->
mem x l
| N (x', _, r) when Ord.compare x x' > 0 ->
mem x r
| _ -> true;;
let rec largest t =
match t with
| L -> failwith "largest: empty tree"
| N (x, _, L) -> x
| N (_, _, r) -> largest r;;
let rec smallest t =
match t with
| L -> failwith "smallest: empty tree"
| N (x, L, _) -> x
| N (_, l, _) -> smallest l;;
let rec delete x t =
match t with
| L -> L
| N (x', l, r) when Ord.compare x x' < 0 ->
N (x', delete x l, r)
| N (x', l, r) when Ord.compare x x' > 0 ->
N (x', l, delete x r)
| N (_, L, L) -> L (* this does not need to be here, its a special case but ill leave it for clarity *)
| N (_, l, L) -> l
| N (_, L, r) -> r
| N (_, l, r) ->
let succ = largest l in
N (succ, delete succ l, r);;
end
@@ -0,0 +1 @@
bstree.ml: Fun List
+20
View File
@@ -0,0 +1,20 @@
module type OrderedType = sig
type t
val compare : t -> t -> int
end
module type S = sig
type elt
type t
val size : t -> int
val height : t -> int
val empty : t
val is_empty : t -> bool
val insert : elt -> t -> t
val of_list : elt list -> t
val mem : elt -> t -> bool
val delete : elt -> t -> t
end
module Make(Ord: OrderedType) : S with type elt = Ord.t
@@ -0,0 +1 @@
bstree.mli:
+86
View File
@@ -0,0 +1,86 @@
module type OrderedType = sig
type t
val compare : t -> t -> int
end
module type S = sig
type elt
type t
val size : t -> int
val height : t -> int
val empty : t
val is_empty : t -> bool
val insert : elt -> t -> t
val of_list : elt list -> t
val mem : elt -> t -> bool
val delete : elt -> t -> t
end
module Make(Ord : OrderedType) = struct
type elt = Ord.t;;
type t = L | N of elt * t * t;;
let rec size t =
match t with
| L -> 0
| N (_, l, r) ->
1 + size l + size r;;
let rec height t =
match t with
| L -> 0
| N (_, l, r) ->
1 + max (height l) (height r);;
let empty = L;;
let is_empty t = t = L;;
let rec insert x t =
match t with
| L -> N (x, L, L)
| N (x', l, r) when Ord.compare x x' < 0 ->
N (x', insert x l, r)
| N (x', l, r) when Ord.compare x x' > 0 ->
N (x', l, insert x r)
| _ -> t;;
let of_list l =
List.fold_left (Fun.flip insert) L l;;
let rec mem x t =
match t with
| L -> false
| N (x', l, _) when Ord.compare x x' < 0 ->
mem x l
| N (x', _, r) when Ord.compare x x' > 0 ->
mem x r
| _ -> true;;
let rec largest t =
match t with
| L -> failwith "largest: empty tree"
| N (x, _, L) -> x
| N (_, _, r) -> largest r;;
let rec smallest t =
match t with
| L -> failwith "smallest: empty tree"
| N (x, L, _) -> x
| N (_, l, _) -> smallest l;;
let rec delete x t =
match t with
| L -> L
| N (x', l, r) when Ord.compare x x' < 0 ->
N (x', delete x l, r)
| N (x', l, r) when Ord.compare x x' > 0 ->
N (x', l, delete x r)
| N (_, L, L) -> L (* this does not need to be here, its a special case but ill leave it for clarity *)
| N (_, l, L) -> l
| N (_, L, r) -> r
| N (_, l, r) ->
let succ = largest l in
N (succ, delete succ l, r);;
end
+20
View File
@@ -0,0 +1,20 @@
module type OrderedType = sig
type t
val compare : t -> t -> int
end
module type S = sig
type elt
type t
val size : t -> int
val height : t -> int
val empty : t
val is_empty : t -> bool
val insert : elt -> t -> t
val of_list : elt list -> t
val mem : elt -> t -> bool
val delete : elt -> t -> t
end
module Make(Ord: OrderedType) : S with type elt = Ord.t
View File
Whitespace-only changes.
+8
View File
@@ -0,0 +1,8 @@
module / struct
module type / sig / interface
open M
let opem M in ..
M.(...)
+37
View File
@@ -0,0 +1,37 @@
type 'a t = 'a list;;
exception Empty
let empty = [];;
let is_empty q = q = [];;
let enqueue x q = q @ [x];;
let dequeue q =
match q with
| [] -> raise Empty
| _ :: xs -> xs;;
let dequeue_opt q =
match q with
| [] -> None
| _ :: xs -> Some xs;;
let front q =
match q with
| [] -> raise Empty
| x :: _ -> x;;
let front_opt q =
match q with
| [] -> None
| x :: _ -> Some x;;
let length q =
List.length q;;
let of_list l = l;;
let to_list q = q;;
+42
View File
@@ -0,0 +1,42 @@
(* queue is empty iff the first list is empty *)
type 'a t = 'a list * 'a list;;
exception Empty;;
let empty = ([], []);;
let is_empty (l, _) = l = [];;
let enqueue x (l1, l2) =
match l1 with
| [] -> [x], l2
| _ -> (l1, x :: l2);;
let dequeue (l1, l2) =
match l1 with
| [] -> raise Empty
| [_] -> (List.rev l2, [])
| _ :: xs -> (xs, l2);;
let dequeue_opt q =
try
Some (dequeue q)
with
| Empty -> None;;
let front (l, _) =
match l with
| [] -> raise Empty
| x :: _ -> x;;
let front_opt (l, _) =
match l with
| [] -> None
| x :: _ -> Some x;;
let of_list l =
List.fold_left (Fun.flip enqueue) empty l;;
let to_list (l1, l2) =
l1 @ List.rev l2;;
+2
View File
@@ -0,0 +1,2 @@
(* bstree with records *)
type 'a t = L | N of {v: 'a; l: 'a t; r: 'a t};;
+7
View File
@@ -0,0 +1,7 @@
let counter =
let c = ref 0 in
(fun () -> incr c; !c);;
let make_counter init =
let c = ref init in
(fun () -> let x = !c in incr c; x);;
+12
View File
@@ -0,0 +1,12 @@
module F = Map.Make(String)
let rec count map =
let word = Scanf.scanf " %s" (fun w -> w) in
if word = "" then map
else count (F.update word (function
| None -> Some 1
| Some n -> Some (n + 1))
map);;
let () =
List.iter (fun (s, n) -> Printf.printf "%s: %d\n" s n) @@ count F.empty;;
+46
View File
@@ -0,0 +1,46 @@
(** rank of node = shortest distance to a leaf (empty node)
* hence, rank of node = 1 + min(rnak of left, rank of right)
* leftist tree has 2 properties:
* For ever node
* * leftist: rnak(left) >= rank(right)
* * min-heap: value(parent) <= value(node)
*)
type 'a t = L | N of int * 'a * 'a t * 'a t;;
exception Empty;;
let rank = function
| L -> 0
| N (rk, _, _, _) -> rk;;
let empty = L;;
let is_empty t = t = L;;
let rec merge t1 t2 =
match t1, t2 with
| t, L | L, t -> t
| N (_, x1, _, _), N (_, x2, _, _) when x2 < x1 ->
merge t2 t1
| N (_, x, l, r), t ->
let t' = merge r t in
if rank t' > rank l then N (1 + rank l, x, t', l)
else N (1 + rank t', x, l, t');;
let insert x t =
merge t (N (1, x, L, L));;
let of_list l = List.fold_left (Fun.flip insert) L l;;
let get_min = function
| L -> raise Empty
| N (_, x, _, _) -> x;;
let delete_min = function
| L -> L
| N (_, _, l, r) -> merge l r;;
let rec to_list t =
if is_empty t then []
else get_min t :: to_list (delete_min t);;
+47
View File
@@ -0,0 +1,47 @@
(*
- a module can contain other modules as well as module type definitions
- a module type/sig (signature) can not contain modules but can contain other sigs
- for a .ml/.mli pair,
* anything not specified in .mli file is hidden
* everything specified in the .mli file must be defined in the .ml file
*)
module M = struct
let f x = 2 * x
end;;
module type S = module type of M;;
module M = struct
let f x = 2 * x;;
let g x = 3 * x;;
module N = struct
type t = int
end
end;;
(* S signature is the same as M if loaded in utop *)
module type S = module type of M;;
(***** EXTENDED MODULES *****)
(* lets extend List module *)
module ListExt = struct
include List;; (* include module to extend *)
let to_array l = Array.of_list l;;
end;;
ListExt.to_array [3;2;7;6;8];;
module F = Map.Make(String);;
(* returns abstract type *)
let m = F.empty |> F.add "hello" 1 |> F.add "hello" 2;;
F.to_list m;;
let incr key m =
F.update key (function | None -> Some 1 | Some x -> Some (x + 1))
m;;
let m = incr "hello" m;;
let m = incr "world" m;;
+16
View File
@@ -0,0 +1,16 @@
let isqrt n = n |> float_of_int |> sqrt |> int_of_float;;
let sieve n =
let is_prime = Array.make n true in
for i = 2 to isqrt n do
if is_prime.(i) then
let j = ref i in
while i * !j < n do
is_prime.(i * !j) <- false;
incr j
done
done;
is_prime.(0) <- false;
is_prime.(1) <- false;
is_prime |> Array.to_list |> List.mapi (fun i b -> (i, b)) |>
List.filter_map (fun (i, b) -> if b then Some i else None);;