new modules and neatened exposure of official stdlib code
This commit is contained in:
parent
e9368e17c1
commit
e25b69bd44
21
README.md
21
README.md
@ -12,15 +12,18 @@ Also note that I use WSL for all OCaml programming, and this is my recommendatio
|
|||||||
|
|
||||||
This library includes the following custom modules:
|
This library includes the following custom modules:
|
||||||
|
|
||||||
|
- Array (for operations on mutable arrays)
|
||||||
- Bool (for basic operations on booleans)
|
- Bool (for basic operations on booleans)
|
||||||
- Char (for basic operations on characters)
|
- Char (for basic operations on characters)
|
||||||
- Fatal (for throwing exceptions, and making assertions)
|
- Fatal (for throwing exceptions, and making assertions)
|
||||||
|
- File (for file IO)
|
||||||
- Float (for basic operations on floating point numbers)
|
- Float (for basic operations on floating point numbers)
|
||||||
- Int (for basic operations on integers)
|
- Int (for basic operations on integers)
|
||||||
- List (functional list data structure)
|
- List (functional list data structure)
|
||||||
- Map (functional map implemented as a red-black tree)
|
- Map (functional map implemented as a red-black tree)
|
||||||
- Option (functions for working with the option monad)
|
- Option (functions for working with the option monad)
|
||||||
- Queue (functional queue implemented as two lists)
|
- Queue (functional queue implemented as two lists)
|
||||||
|
- Random (for pseudorandom generation)
|
||||||
- Set (functional set implemented as a red-black tree)
|
- Set (functional set implemented as a red-black tree)
|
||||||
- Stack (functional stack data structure)
|
- Stack (functional stack data structure)
|
||||||
- String (for basic operations on strings)
|
- String (for basic operations on strings)
|
||||||
@ -29,7 +32,7 @@ This library includes the following custom modules:
|
|||||||
|
|
||||||
## Exposure of Functions from Standard Library
|
## Exposure of Functions from Standard Library
|
||||||
|
|
||||||
Some functions from the OCaml standard library are exposed through this library. They are handled by the `FromStdlib` module which SHOULD NOT be accessed directly in projects using this library. All functions and types from this module that are exposed to be used in projects are redefined in another module and should be accessed there. The reason for this module is to allow the rest of the modules to be compile with the `-nopervasives` flag yet still access a few of the official OCaml standard module functions.
|
Some functions from the OCaml standard library are exposed through this library, for random number generation, file and terminal IO, and arrays. They are handled by direct reference to the `Stdlib` module and therefore all modules are compiled with the `-nopervasives` flag.
|
||||||
|
|
||||||
## Type Declarations and General Functions
|
## Type Declarations and General Functions
|
||||||
|
|
||||||
@ -89,7 +92,7 @@ $(STANDARD_COMPILE) newModule.mli newModule.ml
|
|||||||
Then the final step within `build` also needs to be altered to include the corresponding `.cmx` file.
|
Then the final step within `build` also needs to be altered to include the corresponding `.cmx` file.
|
||||||
|
|
||||||
```
|
```
|
||||||
ocamlopt -a fromStdlib.cmx exposed.cmx int.cmx float.cmx option.cmx stack.cmx list.cmx map.cmx queue.cmx set.cmx tree.cmx string.cmx newModule.cmx -o $(LIB_NAME).cmxa
|
ocamlopt -a exposed.cmx int.cmx float.cmx option.cmx stack.cmx list.cmx map.cmx queue.cmx set.cmx tree.cmx string.cmx newModule.cmx -o $(LIB_NAME).cmxa
|
||||||
```
|
```
|
||||||
|
|
||||||
Just as with the project in the top level, file order should be consistent across compile lines and this final line.
|
Just as with the project in the top level, file order should be consistent across compile lines and this final line.
|
||||||
@ -98,18 +101,8 @@ Just as with the project in the top level, file order should be consistent acros
|
|||||||
|
|
||||||
One of the unfortunate consequences of the way OCaml's compilation works, is that there is a library called the core library (not to be confused with Jane Street's Core), documented [here](https://ocaml.org/manual/core.html), which contains some definitions for types and exceptions, yet does not include the code from the stdlib that uses them. When compiling with the `-nopervasives` flag, this is still included but without the standard library. While this makes sense from the perspective of having some fundamental exceptions always available, having types like `list` included makes it very annoying when implemented a custom standard library (with the benefit of list literals still functioning properly). This quirk is why my library has no type definition for `list`, `bool`, `option`, etc. but still uses these types.
|
One of the unfortunate consequences of the way OCaml's compilation works, is that there is a library called the core library (not to be confused with Jane Street's Core), documented [here](https://ocaml.org/manual/core.html), which contains some definitions for types and exceptions, yet does not include the code from the stdlib that uses them. When compiling with the `-nopervasives` flag, this is still included but without the standard library. While this makes sense from the perspective of having some fundamental exceptions always available, having types like `list` included makes it very annoying when implemented a custom standard library (with the benefit of list literals still functioning properly). This quirk is why my library has no type definition for `list`, `bool`, `option`, etc. but still uses these types.
|
||||||
|
|
||||||
## Planned Changes
|
## Planned Change;
|
||||||
|
|
||||||
The following modules are some that I plan on introducing in future iterations of this project:
|
At some point I would like to remove all dependencies on the actual OCaml standard library by way of custom implementations for all the functions that currently reference the `Stdlib` module, and all external functions using code in the standard library.
|
||||||
|
|
||||||
- Array: for operations with mutable arrays.
|
|
||||||
- Random: for random number generation.
|
|
||||||
- File: for file IO.
|
|
||||||
|
|
||||||
I also intend on modifying the following modules:
|
|
||||||
|
|
||||||
- Terminal: this module still needs input functions.
|
|
||||||
|
|
||||||
## Tests
|
|
||||||
|
|
||||||
Unit tests are also planned for all collection modules, but have not been written yet.
|
Unit tests are also planned for all collection modules, but have not been written yet.
|
50
lib/array.ml
Normal file
50
lib/array.ml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
open General
|
||||||
|
|
||||||
|
|
||||||
|
let of_list = Stdlib.Array.of_list
|
||||||
|
|
||||||
|
let length = Stdlib.Array.length
|
||||||
|
|
||||||
|
let concat = Stdlib.Array.concat
|
||||||
|
|
||||||
|
let append = Stdlib.Array.append
|
||||||
|
|
||||||
|
let get = Stdlib.Array.get
|
||||||
|
|
||||||
|
let set = Stdlib.Array.set
|
||||||
|
|
||||||
|
let map = Stdlib.Array.map
|
||||||
|
|
||||||
|
let create = Stdlib.Array.init
|
||||||
|
|
||||||
|
let heap_sort = Stdlib.Array.sort
|
||||||
|
|
||||||
|
let merge_sort = Stdlib.Array.stable_sort
|
||||||
|
|
||||||
|
let copy = Stdlib.Array.copy
|
||||||
|
|
||||||
|
let linear_search (arr : 'a array) (value : 'a) =
|
||||||
|
let i = ref 0 in
|
||||||
|
|
||||||
|
while (!i < length arr) & (get arr !i <> value) do
|
||||||
|
i := Int.(!i + 1)
|
||||||
|
done;
|
||||||
|
|
||||||
|
get arr !i
|
||||||
|
|
||||||
|
let rec binary_search_helper (arr : 'a array) (value : 'a) (first : int) (last : int) =
|
||||||
|
let midpoint = Int.((first + last) / 2) in
|
||||||
|
|
||||||
|
if midpoint < first or midpoint > last then
|
||||||
|
None
|
||||||
|
else if value < (get arr midpoint) then
|
||||||
|
binary_search_helper arr value first Int.(midpoint - 1)
|
||||||
|
else if (get arr midpoint) < value then
|
||||||
|
binary_search_helper arr value Int.(midpoint + 1) last
|
||||||
|
else if get arr midpoint = value then
|
||||||
|
Some (get arr midpoint)
|
||||||
|
else
|
||||||
|
None
|
||||||
|
|
||||||
|
let binary_search (arr : 'a array) (value : 'a) =
|
||||||
|
binary_search_helper arr value 0 Int.(length arr - 1)
|
28
lib/array.mli
Normal file
28
lib/array.mli
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
open General
|
||||||
|
|
||||||
|
|
||||||
|
val of_list : 'a list -> 'a array
|
||||||
|
|
||||||
|
val length : 'a array -> int
|
||||||
|
|
||||||
|
val concat : 'a array list -> 'a array
|
||||||
|
|
||||||
|
val append : 'a array -> 'a array -> 'a array
|
||||||
|
|
||||||
|
val get : 'a array -> int -> 'a
|
||||||
|
|
||||||
|
val set : 'a array -> int -> 'a -> unit
|
||||||
|
|
||||||
|
val map : ('a -> 'b) -> 'a array -> 'b array
|
||||||
|
|
||||||
|
val create : int -> (int -> 'a) -> 'a array
|
||||||
|
|
||||||
|
val heap_sort : ('a -> 'a -> int) -> 'a array -> unit
|
||||||
|
|
||||||
|
val merge_sort : ('a -> 'a -> int) -> 'a array -> unit
|
||||||
|
|
||||||
|
val copy : 'a array -> 'a array
|
||||||
|
|
||||||
|
val linear_search : 'a array -> 'a -> 'a
|
||||||
|
|
||||||
|
val binary_search : 'a array -> 'a -> 'a option
|
@ -1,3 +1,7 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
let of_string = FromStdlib.bool_of_string_opt
|
|
||||||
|
let of_string = function
|
||||||
|
| "true" -> Some true
|
||||||
|
| "false" -> Some false
|
||||||
|
| _ -> None
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(** Converts the string to a bool, returning option type to account for invalid strings. *)
|
(** Converts the string to a bool, returning option type to account for invalid strings. *)
|
||||||
val of_string : string -> bool option
|
val of_string : string -> bool option
|
10
lib/char.ml
10
lib/char.ml
@ -1,3 +1,11 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
let of_int = FromStdlib.char_of_int
|
|
||||||
|
external unsafe_char_of_int : int -> char = "%identity"
|
||||||
|
|
||||||
|
|
||||||
|
let of_int n =
|
||||||
|
if n < 0 or n > 255 then
|
||||||
|
None
|
||||||
|
else
|
||||||
|
Some (unsafe_char_of_int n)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(** Converts an int to a char. *)
|
(** Converts an int to a char. *)
|
||||||
val of_int : int -> char
|
val of_int : int -> char option
|
11
lib/fatal.ml
11
lib/fatal.ml
@ -1,6 +1,10 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
let failwith = FromStdlib.failwith
|
|
||||||
|
external raise : exn -> 'a = "%raise"
|
||||||
|
|
||||||
|
|
||||||
|
let failwith m = raise (Failure m)
|
||||||
|
|
||||||
let guarantee b =
|
let guarantee b =
|
||||||
if not b then
|
if not b then
|
||||||
@ -8,4 +12,7 @@ let guarantee b =
|
|||||||
|
|
||||||
let guarantee_equal a b =
|
let guarantee_equal a b =
|
||||||
if a <> b then
|
if a <> b then
|
||||||
failwith "guarantee_equal failed."
|
failwith "guarantee_equal failed."
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(** Throws an exception with a message. *)
|
(** Throws an exception with a message. *)
|
||||||
val failwith : string -> 'a
|
val failwith : string -> 'a
|
||||||
|
|
||||||
|
29
lib/file.ml
Normal file
29
lib/file.ml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
open General
|
||||||
|
|
||||||
|
|
||||||
|
let open_out = Stdlib.open_out
|
||||||
|
|
||||||
|
let close_out = Stdlib.close_out
|
||||||
|
|
||||||
|
let printf = Stdlib.Printf.fprintf
|
||||||
|
|
||||||
|
let write_all_text filepath text =
|
||||||
|
let channel = open_out filepath in
|
||||||
|
let _ = printf channel "%s" text in
|
||||||
|
let _ = close_out channel in
|
||||||
|
()
|
||||||
|
|
||||||
|
|
||||||
|
let open_in = Stdlib.open_in
|
||||||
|
|
||||||
|
let close_in = Stdlib.close_in
|
||||||
|
|
||||||
|
let read_n_chars = Stdlib.really_input_string
|
||||||
|
|
||||||
|
let in_channel_length = Stdlib.in_channel_length
|
||||||
|
|
||||||
|
let read_all_text filepath =
|
||||||
|
let channel = open_in filepath in
|
||||||
|
let contents = read_n_chars channel (in_channel_length channel) in
|
||||||
|
let _ = close_in channel in
|
||||||
|
contents
|
26
lib/file.mli
Normal file
26
lib/file.mli
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
open General
|
||||||
|
|
||||||
|
|
||||||
|
(** Opens and returns an output channel at the specified path. *)
|
||||||
|
val open_out : string -> Stdlib.out_channel
|
||||||
|
|
||||||
|
(** Closes the provided output channel. *)
|
||||||
|
val close_out : Stdlib.out_channel -> unit
|
||||||
|
|
||||||
|
(** Formatted printing to a provided output channel. *)
|
||||||
|
val printf : Stdlib.out_channel -> ('a, Stdlib.out_channel, unit) Stdlib.format -> 'a
|
||||||
|
|
||||||
|
(** Writes the given string to a file at the specified filepath. *)
|
||||||
|
val write_all_text : string -> string -> unit
|
||||||
|
|
||||||
|
(** Opens and returns an input channel at the specified path. *)
|
||||||
|
val open_in : string -> Stdlib.in_channel
|
||||||
|
|
||||||
|
(** Closes the provided input channel. *)
|
||||||
|
val close_in : Stdlib.in_channel -> unit
|
||||||
|
|
||||||
|
(** Reads the specified number of characters from the provided input channel as a string. *)
|
||||||
|
val read_n_chars : Stdlib.in_channel -> int -> string
|
||||||
|
|
||||||
|
(** Reads from the specified file as a string. *)
|
||||||
|
val read_all_text : string -> string
|
21
lib/float.ml
21
lib/float.ml
@ -1,11 +1,22 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
let ( + ) a b = FromStdlib.plus_float a b
|
|
||||||
|
|
||||||
let ( - ) a b = FromStdlib.minus_float a b
|
external ( + ) : float -> float -> float = "%addfloat"
|
||||||
|
|
||||||
let ( * ) a b = FromStdlib.multiply_float a b
|
external ( - ) : float -> float -> float = "%subfloat"
|
||||||
|
|
||||||
let ( / ) a b = FromStdlib.divide_float a b
|
external ( * ) : float -> float -> float = "%mulfloat"
|
||||||
|
|
||||||
let of_string = FromStdlib.float_of_string_opt
|
external ( / ) : float -> float -> float = "%divfloat"
|
||||||
|
|
||||||
|
|
||||||
|
external float_of_string : string -> float = "caml_float_of_string"
|
||||||
|
|
||||||
|
|
||||||
|
let of_string s =
|
||||||
|
try
|
||||||
|
Some (float_of_string s)
|
||||||
|
with
|
||||||
|
Failure _ -> None
|
||||||
|
|
||||||
|
external of_int : int -> float = "%floatofint"
|
@ -1,12 +1,16 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
val ( + ) : float -> float -> float
|
|
||||||
|
|
||||||
val ( - ) : float -> float -> float
|
external ( + ) : float -> float -> float = "%addfloat"
|
||||||
|
|
||||||
val ( * ) : float -> float -> float
|
external ( - ) : float -> float -> float = "%subfloat"
|
||||||
|
|
||||||
val ( / ) : float -> float -> float
|
external ( * ) : float -> float -> float = "%mulfloat"
|
||||||
|
|
||||||
|
external ( / ) : float -> float -> float = "%divfloat"
|
||||||
|
|
||||||
(** Converts the string to a float, returning option type to account for invalid strings. *)
|
(** Converts the string to a float, returning option type to account for invalid strings. *)
|
||||||
val of_string : string -> float option
|
val of_string : string -> float option
|
||||||
|
|
||||||
|
(** Converts the int to a float. *)
|
||||||
|
val of_int : int -> float
|
@ -1,79 +0,0 @@
|
|||||||
(* https://github.com/ocaml/ocaml/blob/cce52acc7c7903e92078e9fe40745e11a1b944f0/stdlib/pervasives.ml *)
|
|
||||||
|
|
||||||
(* For fatal.ml *)
|
|
||||||
let failwith = Stdlib.failwith
|
|
||||||
|
|
||||||
|
|
||||||
(* For terminal.ml *)
|
|
||||||
let printf = Printf.printf
|
|
||||||
type 'a printf_format = ('a, out_channel, unit) format
|
|
||||||
|
|
||||||
|
|
||||||
(* For int.ml *)
|
|
||||||
external int_of_char : char -> int = "%identity"
|
|
||||||
let int_of_string_opt = int_of_string_opt
|
|
||||||
|
|
||||||
external plus_int : int -> int -> int = "%addint"
|
|
||||||
external minus_int : int -> int -> int = "%subint"
|
|
||||||
external multiply_int : int -> int -> int = "%mulint"
|
|
||||||
external divide_int : int -> int -> int = "%divint"
|
|
||||||
external mod_int : int -> int -> int = "%modint"
|
|
||||||
|
|
||||||
|
|
||||||
(* For float.ml *)
|
|
||||||
let float_of_string_opt = float_of_string_opt
|
|
||||||
|
|
||||||
external plus_float : float -> float -> float = "%addfloat"
|
|
||||||
external minus_float : float -> float -> float = "%subfloat"
|
|
||||||
external multiply_float : float -> float -> float = "%mulfloat"
|
|
||||||
external divide_float : float -> float -> float = "%divfloat"
|
|
||||||
|
|
||||||
|
|
||||||
(* For char.ml *)
|
|
||||||
let char_of_int = char_of_int
|
|
||||||
|
|
||||||
|
|
||||||
(* For string.ml *)
|
|
||||||
let string_of_bool = string_of_bool
|
|
||||||
let string_of_int = string_of_int
|
|
||||||
let string_of_float = string_of_float
|
|
||||||
|
|
||||||
external string_length : string -> int = "%string_length"
|
|
||||||
|
|
||||||
(* This block are not exposed *)
|
|
||||||
external bytes_create : int -> bytes = "caml_create_bytes"
|
|
||||||
external string_blit : string -> int -> bytes -> int -> int -> unit
|
|
||||||
= "caml_blit_string" [@@noalloc]
|
|
||||||
external bytes_blit : bytes -> int -> bytes -> int -> int -> unit
|
|
||||||
= "caml_blit_bytes" [@@noalloc]
|
|
||||||
external bytes_unsafe_to_string : bytes -> string = "%bytes_to_string"
|
|
||||||
|
|
||||||
let string_concat s1 s2 =
|
|
||||||
let l1 = string_length s1 and l2 = string_length s2 in
|
|
||||||
let s = bytes_create (l1 + l2) in
|
|
||||||
string_blit s1 0 s 0 l1;
|
|
||||||
string_blit s2 0 s l1 l2;
|
|
||||||
bytes_unsafe_to_string s
|
|
||||||
|
|
||||||
|
|
||||||
(* For bool.ml *)
|
|
||||||
let bool_of_string_opt = bool_of_string_opt
|
|
||||||
|
|
||||||
|
|
||||||
(* For general.ml *)
|
|
||||||
external equal : 'a -> 'a -> bool = "%equal"
|
|
||||||
external not_equal : 'a -> 'a -> bool = "%notequal"
|
|
||||||
|
|
||||||
external less_than : 'a -> 'a -> bool = "%lessthan"
|
|
||||||
external greater_than : 'a -> 'a -> bool = "%greaterthan"
|
|
||||||
external less_than_or_equal : 'a -> 'a -> bool = "%lessequal"
|
|
||||||
external greater_than_or_equal : 'a -> 'a -> bool = "%greaterequal"
|
|
||||||
|
|
||||||
external not : bool -> bool = "%boolnot"
|
|
||||||
external or_ : bool -> bool -> bool = "%sequor"
|
|
||||||
external and_ : bool -> bool -> bool = "%sequand"
|
|
||||||
|
|
||||||
external pipeline : 'a -> ('a -> 'b) -> 'b = "%revapply"
|
|
||||||
external ignore : 'a -> unit = "%ignore"
|
|
||||||
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
|||||||
(* For fatal.ml *)
|
|
||||||
val failwith : string -> 'a
|
|
||||||
|
|
||||||
|
|
||||||
(* For terminal.ml *)
|
|
||||||
val printf : ('a, out_channel, unit) format -> 'a
|
|
||||||
type 'a printf_format = ('a, out_channel, unit) format
|
|
||||||
|
|
||||||
|
|
||||||
(* For int.ml *)
|
|
||||||
external int_of_char : char -> int = "%identity"
|
|
||||||
val int_of_string_opt : string -> int option
|
|
||||||
|
|
||||||
external plus_int : int -> int -> int = "%addint"
|
|
||||||
external minus_int : int -> int -> int = "%subint"
|
|
||||||
external multiply_int : int -> int -> int = "%mulint"
|
|
||||||
external divide_int : int -> int -> int = "%divint"
|
|
||||||
external mod_int : int -> int -> int = "%modint"
|
|
||||||
|
|
||||||
|
|
||||||
(* For float.ml *)
|
|
||||||
val float_of_string_opt : string -> float option
|
|
||||||
|
|
||||||
external plus_float : float -> float -> float = "%addfloat"
|
|
||||||
external minus_float : float -> float -> float = "%subfloat"
|
|
||||||
external multiply_float : float -> float -> float = "%mulfloat"
|
|
||||||
external divide_float : float -> float -> float = "%divfloat"
|
|
||||||
|
|
||||||
|
|
||||||
(* For char.ml *)
|
|
||||||
val char_of_int : int -> char
|
|
||||||
|
|
||||||
|
|
||||||
(* For string.ml *)
|
|
||||||
val string_of_bool : bool -> string
|
|
||||||
val string_of_int : int -> string
|
|
||||||
val string_of_float : float -> string
|
|
||||||
|
|
||||||
external string_length : string -> int = "%string_length"
|
|
||||||
val string_concat : string -> string -> string
|
|
||||||
|
|
||||||
|
|
||||||
(* For bool.ml *)
|
|
||||||
val bool_of_string_opt : string -> bool option
|
|
||||||
|
|
||||||
|
|
||||||
(* For general.ml *)
|
|
||||||
external equal : 'a -> 'a -> bool = "%equal"
|
|
||||||
external not_equal : 'a -> 'a -> bool = "%notequal"
|
|
||||||
|
|
||||||
external less_than : 'a -> 'a -> bool = "%lessthan"
|
|
||||||
external greater_than : 'a -> 'a -> bool = "%greaterthan"
|
|
||||||
external less_than_or_equal : 'a -> 'a -> bool = "%lessequal"
|
|
||||||
external greater_than_or_equal : 'a -> 'a -> bool = "%greaterequal"
|
|
||||||
|
|
||||||
external not : bool -> bool = "%boolnot"
|
|
||||||
external or_ : bool -> bool -> bool = "%sequor"
|
|
||||||
external and_ : bool -> bool -> bool = "%sequand"
|
|
||||||
|
|
||||||
external pipeline : 'a -> ('a -> 'b) -> 'b = "%revapply"
|
|
||||||
external ignore : 'a -> unit = "%ignore"
|
|
@ -12,7 +12,7 @@ type 'a tree =
|
|||||||
| Leaf
|
| Leaf
|
||||||
| Branch of 'a * 'a tree list
|
| Branch of 'a * 'a tree list
|
||||||
|
|
||||||
let ignore = FromStdlib.ignore
|
let ignore (a : 'a) = ()
|
||||||
|
|
||||||
let id (x : 'a) = x
|
let id (x : 'a) = x
|
||||||
|
|
||||||
@ -20,23 +20,38 @@ let ( >> ) f g x = g (f x)
|
|||||||
|
|
||||||
let ( << ) g f x = g (f x)
|
let ( << ) g f x = g (f x)
|
||||||
|
|
||||||
let ( |> ) = FromStdlib.pipeline
|
let ( |> ) f g = g f
|
||||||
|
|
||||||
let ( = ) = FromStdlib.equal
|
external ( = ) : 'a -> 'a -> bool = "%equal"
|
||||||
|
|
||||||
let ( <> ) = FromStdlib.not_equal
|
external ( <> ) : 'a -> 'a -> bool = "%notequal"
|
||||||
|
|
||||||
let ( < ) = FromStdlib.less_than
|
external ( < ) : 'a -> 'a -> bool = "%lessthan"
|
||||||
|
|
||||||
let ( > ) = FromStdlib.greater_than
|
external ( > ) : 'a -> 'a -> bool = "%greaterthan"
|
||||||
|
|
||||||
let ( <= ) = FromStdlib.less_than_or_equal
|
external ( <= ) : 'a -> 'a -> bool = "%lessequal"
|
||||||
|
|
||||||
let ( >= ) = FromStdlib.greater_than_or_equal
|
external ( >= ) : 'a -> 'a -> bool = "%greaterequal"
|
||||||
|
|
||||||
let not = FromStdlib.not
|
let not = function
|
||||||
|
| true -> false
|
||||||
|
| false -> true
|
||||||
|
|
||||||
let ( or ) = FromStdlib.or_
|
external ( or ) : bool -> bool -> bool = "%sequor"
|
||||||
|
|
||||||
|
external ( & ) : bool -> bool -> bool = "%sequand"
|
||||||
|
|
||||||
|
type 'a ref =
|
||||||
|
{ mutable contents : 'a }
|
||||||
|
|
||||||
|
let ref a =
|
||||||
|
{ contents = a }
|
||||||
|
|
||||||
|
let ( := ) (cell : 'a ref) (contents : 'a) =
|
||||||
|
cell.contents <- contents
|
||||||
|
|
||||||
|
let ( ! ) (cell : 'a ref) =
|
||||||
|
cell.contents
|
||||||
|
|
||||||
let ( & ) = FromStdlib.and_
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
(** Purely functional queue, implemented as a pair of lists. *)
|
(** Purely functional queue, implemented as a pair of lists. *)
|
||||||
type 'a queue = { front : 'a list; back : 'a list }
|
type 'a queue = { front : 'a list; back : 'a list }
|
||||||
|
|
||||||
|
(** Result type for error handling. *)
|
||||||
type 'a result =
|
type 'a result =
|
||||||
| Error of string
|
| Error of string
|
||||||
| Success of 'a
|
| Success of 'a
|
||||||
@ -10,7 +11,7 @@ type 'a stack =
|
|||||||
| Empty
|
| Empty
|
||||||
| Stacked of 'a * 'a stack
|
| Stacked of 'a * 'a stack
|
||||||
|
|
||||||
(* A purely functional tree with arbitrarily many branches at each node. *)
|
(**A purely functional tree with arbitrarily many branches at each node. *)
|
||||||
type 'a tree =
|
type 'a tree =
|
||||||
| Leaf
|
| Leaf
|
||||||
| Branch of 'a * 'a tree list
|
| Branch of 'a * 'a tree list
|
||||||
@ -31,28 +32,40 @@ val ( << ) : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
|
|||||||
val ( |> ) : 'a -> ('a -> 'b) -> 'b
|
val ( |> ) : 'a -> ('a -> 'b) -> 'b
|
||||||
|
|
||||||
(** Checks for structural equality. *)
|
(** Checks for structural equality. *)
|
||||||
val ( = ) : 'a -> 'a -> bool
|
external ( = ) : 'a -> 'a -> bool = "%equal"
|
||||||
|
|
||||||
(** Checks for structural inequality. *)
|
(** Checks for structural inequality. *)
|
||||||
val ( <> ) : 'a -> 'a -> bool
|
external ( <> ) : 'a -> 'a -> bool = "%notequal"
|
||||||
|
|
||||||
(** Polymorphic less than. *)
|
(** Polymorphic less than. *)
|
||||||
val ( < ) : 'a -> 'a -> bool
|
external ( < ) : 'a -> 'a -> bool = "%lessthan"
|
||||||
|
|
||||||
(** Polymorphic greater than. *)
|
(** Polymorphic greater than. *)
|
||||||
val ( > ) : 'a -> 'a -> bool
|
external ( > ) : 'a -> 'a -> bool = "%greaterthan"
|
||||||
|
|
||||||
(** Polymorphic less than or equal to. *)
|
(** Polymorphic less than or equal to. *)
|
||||||
val ( <= ) : 'a -> 'a -> bool
|
external ( <= ) : 'a -> 'a -> bool = "%lessequal"
|
||||||
|
|
||||||
(** Polymorphic greater than or equal to. *)
|
(** Polymorphic greater than or equal to. *)
|
||||||
val ( >= ) : 'a -> 'a -> bool
|
external ( >= ) : 'a -> 'a -> bool = "%greaterequal"
|
||||||
|
|
||||||
(** Logical negation. *)
|
(** Logical negation. *)
|
||||||
val not : bool -> bool
|
val not : bool -> bool
|
||||||
|
|
||||||
(** Logical or (infix). *)
|
(** Logical or (infix). *)
|
||||||
val ( or ) : bool -> bool -> bool
|
external ( or ) : bool -> bool -> bool = "%sequor"
|
||||||
|
|
||||||
(** Logical and. *)
|
(** Logical and. *)
|
||||||
val ( & ) : bool -> bool -> bool
|
external ( & ) : bool -> bool -> bool = "%sequand"
|
||||||
|
|
||||||
|
(** Reference cells for mutable variables. *)
|
||||||
|
type 'a ref = { mutable contents : 'a; }
|
||||||
|
|
||||||
|
(** Creates a reference cell. *)
|
||||||
|
val ref : 'a -> 'a ref
|
||||||
|
|
||||||
|
(** Updates a reference cell. *)
|
||||||
|
val ( := ) : 'a ref -> 'a -> unit
|
||||||
|
|
||||||
|
(** Returns the contents of a reference cell. *)
|
||||||
|
val ( ! ) : 'a ref -> 'a
|
24
lib/int.ml
24
lib/int.ml
@ -1,16 +1,26 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
let ( + ) a b = FromStdlib.plus_int a b
|
|
||||||
|
|
||||||
let ( - ) a b = FromStdlib.minus_int a b
|
external ( + ) : int -> int -> int = "%addint"
|
||||||
|
|
||||||
let ( * ) a b = FromStdlib.multiply_int a b
|
external ( - ) : int -> int -> int = "%subint"
|
||||||
|
|
||||||
let ( / ) a b = FromStdlib.divide_int a b
|
external ( * ) : int -> int -> int = "%mulint"
|
||||||
|
|
||||||
let ( mod ) a b = FromStdlib.mod_int a b
|
external ( / ) : int -> int -> int = "%divint"
|
||||||
|
|
||||||
|
external ( mod ) : int -> int -> int = "%modint"
|
||||||
|
|
||||||
|
external of_char : char -> int = "%identity"
|
||||||
|
|
||||||
|
|
||||||
|
external int_of_string : string -> int = "caml_int_of_string"
|
||||||
|
|
||||||
|
let of_string s =
|
||||||
|
try
|
||||||
|
Some (int_of_string s)
|
||||||
|
with
|
||||||
|
| Failure _ -> None
|
||||||
|
|
||||||
let of_char = FromStdlib.int_of_char
|
|
||||||
|
|
||||||
let of_string = FromStdlib.int_of_string_opt
|
|
||||||
|
|
||||||
|
13
lib/int.mli
13
lib/int.mli
@ -1,17 +1,18 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
val ( + ) : int -> int -> int
|
|
||||||
|
|
||||||
val ( - ) : int -> int -> int
|
external ( + ) : int -> int -> int = "%addint"
|
||||||
|
|
||||||
val ( * ) : int -> int -> int
|
external ( - ) : int -> int -> int = "%subint"
|
||||||
|
|
||||||
val ( / ) : int -> int -> int
|
external ( * ) : int -> int -> int = "%mulint"
|
||||||
|
|
||||||
val ( mod ) : int -> int -> int
|
external ( / ) : int -> int -> int = "%divint"
|
||||||
|
|
||||||
|
external ( mod ) : int -> int -> int = "%modint"
|
||||||
|
|
||||||
(** Converts the char to an int. *)
|
(** Converts the char to an int. *)
|
||||||
val of_char : char -> int
|
external of_char : char -> int = "%identity"
|
||||||
|
|
||||||
(** Converts the string to an int, returning option type to account for invalid strings. *)
|
(** Converts the string to an int, returning option type to account for invalid strings. *)
|
||||||
val of_string : string -> int option
|
val of_string : string -> int option
|
13
lib/list.ml
13
lib/list.ml
@ -1,7 +1,15 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
let empty : 'a list = []
|
let empty : 'a list = []
|
||||||
|
|
||||||
|
let rec length_helper (list : 'a list) (length : int) =
|
||||||
|
match list with
|
||||||
|
| [] -> length
|
||||||
|
| _ :: xs -> length_helper xs Int.(length + 1)
|
||||||
|
|
||||||
|
let length (list : 'a list) = length_helper list 0
|
||||||
|
|
||||||
let head (ls : 'a list) : 'a option =
|
let head (ls : 'a list) : 'a option =
|
||||||
match ls with
|
match ls with
|
||||||
| x :: xs -> Some x
|
| x :: xs -> Some x
|
||||||
@ -142,4 +150,7 @@ let rec initialize_helper (f : int -> 'a) (length : int) (index : int) (acc : 'a
|
|||||||
initialize_helper f length Int.(index + 1) ((f index) :: acc)
|
initialize_helper f length Int.(index + 1) ((f index) :: acc)
|
||||||
|
|
||||||
let initialize (f : int -> 'a) (length : int) : 'a list =
|
let initialize (f : int -> 'a) (length : int) : 'a list =
|
||||||
initialize_helper f length 0 []
|
initialize_helper f length 0 []
|
||||||
|
|
||||||
|
let of_array =
|
||||||
|
Stdlib.Array.to_list
|
@ -1,8 +1,12 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(** The empty list *)
|
(** The empty list *)
|
||||||
val empty : 'a list
|
val empty : 'a list
|
||||||
|
|
||||||
|
(** Calculates the length of the given list. Runs in O(n) and should be stored rather then recalculated if many calls are made on an unchanging list. *)
|
||||||
|
val length : 'a list -> int
|
||||||
|
|
||||||
(** Returns Some [x] if [x] is the head of the list, or None for the empty list. Runs in O(1). *)
|
(** Returns Some [x] if [x] is the head of the list, or None for the empty list. Runs in O(1). *)
|
||||||
val head : 'a list -> 'a option
|
val head : 'a list -> 'a option
|
||||||
|
|
||||||
@ -55,4 +59,7 @@ val filter_rev_tr : ('a -> bool) -> 'a list -> 'a list
|
|||||||
val find : ('a -> bool) -> 'a list -> ('a * int) option
|
val find : ('a -> bool) -> 'a list -> ('a * int) option
|
||||||
|
|
||||||
(** Initializes a list using a length and a function from the index to the desired list value. Runs in O(n). *)
|
(** Initializes a list using a length and a function from the index to the desired list value. Runs in O(n). *)
|
||||||
val initialize : (int -> 'a) -> int -> 'a list
|
val initialize : (int -> 'a) -> int -> 'a list
|
||||||
|
|
||||||
|
(* Creates a list from the provided array. *)
|
||||||
|
val of_array : 'a array -> 'a list
|
11
lib/makefile
11
lib/makefile
@ -3,13 +3,10 @@ STANDARD_COMPILE = ocamlopt $(STANDARD_FLAGS) -nopervasives -c
|
|||||||
LIB_NAME = library
|
LIB_NAME = library
|
||||||
|
|
||||||
build:
|
build:
|
||||||
# fromStdlib manages things that need to be exposed from the standard library
|
make clean
|
||||||
ocamlopt $(STANDARD_FLAGS) -c fromStdlib.mli fromStdlib.ml
|
|
||||||
|
|
||||||
# types and functions that should be opened module wide
|
|
||||||
ocamlopt $(STANDARD_FLAGS) -nopervasives -c general.mli general.ml
|
ocamlopt $(STANDARD_FLAGS) -nopervasives -c general.mli general.ml
|
||||||
|
|
||||||
# the following files make up the core custom standard library code
|
|
||||||
$(STANDARD_COMPILE) fatal.mli fatal.ml
|
$(STANDARD_COMPILE) fatal.mli fatal.ml
|
||||||
$(STANDARD_COMPILE) int.mli int.ml
|
$(STANDARD_COMPILE) int.mli int.ml
|
||||||
$(STANDARD_COMPILE) float.mli float.ml
|
$(STANDARD_COMPILE) float.mli float.ml
|
||||||
@ -24,9 +21,11 @@ build:
|
|||||||
$(STANDARD_COMPILE) char.mli char.ml
|
$(STANDARD_COMPILE) char.mli char.ml
|
||||||
$(STANDARD_COMPILE) bool.mli bool.ml
|
$(STANDARD_COMPILE) bool.mli bool.ml
|
||||||
$(STANDARD_COMPILE) terminal.mli terminal.ml
|
$(STANDARD_COMPILE) terminal.mli terminal.ml
|
||||||
|
$(STANDARD_COMPILE) file.mli file.ml
|
||||||
|
$(STANDARD_COMPILE) array.mli array.ml
|
||||||
|
$(STANDARD_COMPILE) random.mli random.ml
|
||||||
|
|
||||||
ocamlopt -a fromStdlib.cmx general.cmx fatal.cmx int.cmx float.cmx option.cmx stack.cmx list.cmx map.cmx queue.cmx set.cmx tree.cmx string.cmx char.cmx bool.cmx terminal.cmx -o $(LIB_NAME).cmxa
|
ocamlopt -a general.cmx fatal.cmx int.cmx float.cmx option.cmx stack.cmx list.cmx map.cmx queue.cmx set.cmx tree.cmx string.cmx char.cmx bool.cmx terminal.cmx file.cmx array.cmx random.cmx -o $(LIB_NAME).cmxa
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.a *.s *.cmi *.cmx *.cmxa *.cmo *.cma
|
rm -f *.o *.a *.s *.cmi *.cmx *.cmxa *.cmo *.cma
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
module type Map = sig
|
module type Map = sig
|
||||||
type key
|
type key
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
module type Map = sig
|
module type Map = sig
|
||||||
(** The type of keys in the map. *)
|
(** The type of keys in the map. *)
|
||||||
type key
|
type key
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
let return (x : 'a) : 'a option = Some x
|
let return (x : 'a) : 'a option = Some x
|
||||||
|
|
||||||
let ( ~= ) = return
|
let ( ~= ) = return
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(* Monadic return for option type. Trivially boxes the variable of type 'a into a 'a option by applying the Some constructor. *)
|
(* Monadic return for option type. Trivially boxes the variable of type 'a into a 'a option by applying the Some constructor. *)
|
||||||
val return : 'a -> 'a option
|
val return : 'a -> 'a option
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
open List
|
open List
|
||||||
|
|
||||||
|
|
||||||
let enqueue (a : 'a) (qu : 'a queue) : 'a queue =
|
let enqueue (a : 'a) (qu : 'a queue) : 'a queue =
|
||||||
{ qu with front = a :: qu.back }
|
{ qu with front = a :: qu.back }
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(** Adds an element to the back of the queue, returning the new queue. Runs in O(1). *)
|
(** Adds an element to the back of the queue, returning the new queue. Runs in O(1). *)
|
||||||
val enqueue : 'a -> 'a queue -> 'a queue
|
val enqueue : 'a -> 'a queue -> 'a queue
|
||||||
|
|
||||||
|
17
lib/random.ml
Normal file
17
lib/random.ml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
open General
|
||||||
|
|
||||||
|
|
||||||
|
let init = Stdlib.Random.self_init
|
||||||
|
|
||||||
|
|
||||||
|
let integer low high =
|
||||||
|
init ();
|
||||||
|
Int.((Stdlib.Random.int (high - low)) + low)
|
||||||
|
|
||||||
|
let float low high =
|
||||||
|
init ();
|
||||||
|
Float.((Stdlib.Random.float (high - low)) + low)
|
||||||
|
|
||||||
|
let boolean =
|
||||||
|
init ();
|
||||||
|
Stdlib.Random.bool
|
11
lib/random.mli
Normal file
11
lib/random.mli
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
open General
|
||||||
|
|
||||||
|
|
||||||
|
(** Generates a random integer between low (inclusive) and high (exclusive). *)
|
||||||
|
val integer : int -> int -> int
|
||||||
|
|
||||||
|
(** Generates a random float between low (inclusive) and high (exclusive). *)
|
||||||
|
val float : float -> float -> float
|
||||||
|
|
||||||
|
(** Generates a random boolean at even odds. *)
|
||||||
|
val boolean : unit -> bool
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
module type RBTreeSet = sig
|
module type RBTreeSet = sig
|
||||||
type member
|
type member
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
module type RBTreeSet = sig
|
module type RBTreeSet = sig
|
||||||
(** Type of members in the set. *)
|
(** Type of members in the set. *)
|
||||||
type member
|
type member
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
let pop (st : 'a stack) : 'a option * 'a stack =
|
let pop (st : 'a stack) : 'a option * 'a stack =
|
||||||
match st with
|
match st with
|
||||||
| Empty -> (None, Empty)
|
| Empty -> (None, Empty)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(** Removes the top element from the stack, returning a tuple of the new stack, and None if the stack was empty, or Some [x] if [x] was on top of the stack. Popping an empty stack will result in the returned stack also being empty. Runs in O(1). *)
|
(** Removes the top element from the stack, returning a tuple of the new stack, and None if the stack was empty, or Some [x] if [x] was on top of the stack. Popping an empty stack will result in the returned stack also being empty. Runs in O(1). *)
|
||||||
val pop : 'a stack -> 'a option * 'a stack
|
val pop : 'a stack -> 'a option * 'a stack
|
||||||
|
|
||||||
|
@ -1,11 +1,49 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
let ( + ) = FromStdlib.string_concat
|
|
||||||
|
|
||||||
let length = FromStdlib.string_length
|
external bytes_create : int -> bytes = "caml_create_bytes"
|
||||||
|
external string_blit : string -> int -> bytes -> int -> int -> unit = "caml_blit_string" [@@noalloc]
|
||||||
|
external bytes_blit : bytes -> int -> bytes -> int -> int -> unit = "caml_blit_bytes" [@@noalloc]
|
||||||
|
external bytes_unsafe_to_string : bytes -> string = "%bytes_to_string"
|
||||||
|
external format_int : string -> int -> string = "caml_format_int"
|
||||||
|
external format_float : string -> float -> string = "caml_format_float"
|
||||||
|
|
||||||
let of_int = FromStdlib.string_of_int
|
|
||||||
|
|
||||||
let of_float = FromStdlib.string_of_float
|
external length : string -> int = "%string_length"
|
||||||
|
|
||||||
let of_bool = FromStdlib.string_of_bool
|
let of_int n =
|
||||||
|
format_int "%d" n
|
||||||
|
|
||||||
|
let of_bool bool =
|
||||||
|
if bool then
|
||||||
|
"true"
|
||||||
|
else
|
||||||
|
"false"
|
||||||
|
|
||||||
|
let ( + ) s1 s2 =
|
||||||
|
let l1 = length s1 in
|
||||||
|
let l2 = length s2 in
|
||||||
|
|
||||||
|
let s = bytes_create Int.(l1 + l2) in
|
||||||
|
|
||||||
|
string_blit s1 0 s 0 l1;
|
||||||
|
string_blit s2 0 s l1 l2;
|
||||||
|
|
||||||
|
bytes_unsafe_to_string s
|
||||||
|
|
||||||
|
|
||||||
|
external string_get : string -> int -> char = "%string_safe_get"
|
||||||
|
let valid_float_lexem s =
|
||||||
|
let l = length s in
|
||||||
|
let rec loop i =
|
||||||
|
if i >= l then s + "." else
|
||||||
|
match string_get s i with
|
||||||
|
| '0' .. '9' | '-' -> loop Int.(i + 1)
|
||||||
|
| _ -> s
|
||||||
|
in
|
||||||
|
|
||||||
|
loop 0
|
||||||
|
|
||||||
|
|
||||||
|
let of_float f =
|
||||||
|
valid_float_lexem (format_float "%.12g" f)
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
(** Concatenates two strings together in the provided order. *)
|
|
||||||
val ( + ) : string -> string -> string
|
|
||||||
|
|
||||||
(** Calculates the length of the provided string. *)
|
(** Calculates the length of the provided string. *)
|
||||||
val length : string -> int
|
external length : string -> int = "%string_length"
|
||||||
|
|
||||||
(** Converts an int to a string. *)
|
(** Converts an int to a string. *)
|
||||||
val of_int : int -> string
|
val of_int : int -> string
|
||||||
@ -14,3 +12,6 @@ val of_float : float -> string
|
|||||||
|
|
||||||
(** Converts a boolean to a string. *)
|
(** Converts a boolean to a string. *)
|
||||||
val of_bool : bool -> string
|
val of_bool : bool -> string
|
||||||
|
|
||||||
|
(** Concatenates two strings together in the provided order. *)
|
||||||
|
val ( + ) : string -> string -> string
|
@ -1,6 +1,8 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
let printf = FromStdlib.printf
|
|
||||||
|
|
||||||
|
let printf = Stdlib.Printf.printf
|
||||||
|
|
||||||
let print s = printf "%s" s
|
let print s = printf "%s" s
|
||||||
|
|
||||||
|
let read_line = Stdlib.read_line
|
@ -1,7 +1,11 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(** Formatted print to terminal. *)
|
(** Formatted print to terminal. *)
|
||||||
val printf : 'a FromStdlib.printf_format -> 'a
|
val printf : ('a, Stdlib.out_channel, unit) Stdlib.format -> 'a
|
||||||
|
|
||||||
(** Prints the provided string to the terminal. *)
|
(** Prints the provided string to the terminal. *)
|
||||||
val print : string -> unit
|
val print : string -> unit
|
||||||
|
|
||||||
|
(** Reads an input line from the terminal. *)
|
||||||
|
val read_line : unit -> string
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
let combine (tr1 : 'a tree) (tr2 : 'a tree) (topBranch : 'a) : 'a tree =
|
let combine (tr1 : 'a tree) (tr2 : 'a tree) (topBranch : 'a) : 'a tree =
|
||||||
Branch (topBranch, tr1 :: tr2 :: [])
|
Branch (topBranch, tr1 :: tr2 :: [])
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
open General
|
open General
|
||||||
|
|
||||||
|
|
||||||
(* Combines two trees of the same type, with the specified value at the new top node. Runs in O(1). *)
|
(* Combines two trees of the same type, with the specified value at the new top node. Runs in O(1). *)
|
||||||
val combine : 'a tree -> 'a tree -> 'a -> 'a tree
|
val combine : 'a tree -> 'a tree -> 'a -> 'a tree
|
||||||
|
|
||||||
|
4
makefile
4
makefile
@ -5,10 +5,10 @@ build:
|
|||||||
ocamlopt $(CUSTOM_LIBRARY_LOCATION)/library.cmxa -o program
|
ocamlopt $(CUSTOM_LIBRARY_LOCATION)/library.cmxa -o program
|
||||||
|
|
||||||
mostlyclean:
|
mostlyclean:
|
||||||
rm -f *.o *.a *.s *.cmi *.cmx *.cmxa *.cmo *.cma main.mli
|
rm -f *.o *.a *.s *.cmi *.cmx *.cmxa *.cmo *.cma
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.a *.s *.cmi *.cmx *.cmxa *.cmo *.cma main.mli program
|
rm -f *.o *.a *.s *.cmi *.cmx *.cmxa *.cmo *.cma program
|
||||||
|
|
||||||
make install:
|
make install:
|
||||||
make build
|
make build
|
||||||
|
Loading…
Reference in New Issue
Block a user