Created
June 28, 2022 12:27
-
-
Save aur3l14no/354946a82001523b456adda1b0aa060f to your computer and use it in GitHub Desktop.
OCaml Modular Programming
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module type BrokenRing = sig | |
type t | |
val zero : t | |
val one : t | |
val ( + ) : t -> t -> t | |
val ( ~- ) : t -> t | |
val ( * ) : t -> t -> t | |
val to_string : t -> string | |
end | |
module type BrokenField = sig | |
include BrokenRing | |
val ( / ) : t -> t -> t | |
end | |
module type Ring = sig | |
include BrokenRing | |
val of_int : int -> t | |
end | |
module type Field = sig | |
include BrokenField | |
val of_int : int -> t | |
end | |
module type Impl = BrokenField | |
module Int = struct | |
type t = int | |
let zero = 0 | |
let one = 1 | |
let ( + ) = ( + ) | |
let ( ~- ) = ( ~- ) | |
let ( * ) = ( * ) | |
let ( / ) = ( / ) | |
let to_string = string_of_int | |
end | |
module Float = struct | |
type t = float | |
let zero = 0. | |
let one = 1. | |
let ( + ) = ( +. ) | |
let ( ~- ) = ( ~-. ) | |
let ( * ) = ( *. ) | |
let ( / ) = ( /. ) | |
let to_string = string_of_float | |
end | |
module AddOfInt (M : BrokenField) = struct | |
include M | |
let of_int n : M.t = | |
let rec f n x = | |
if n = 0 then x | |
else if n < 0 then f (Stdlib.( + ) n 1) (M.( + ) x @@ M.( ~- ) M.one) | |
else f (Stdlib.( - ) n 1) M.(x + M.one) | |
in | |
f n M.(one + ~- one) | |
end | |
module MakeRational (M : BrokenField) : BrokenField = struct | |
type t = M.t * M.t | |
let zero = M.(zero, zero) | |
let one = M.(one, one) | |
let ( + ) (a, b) (c, d) = M.((a * d + c * b), b * d) | |
let ( ~- ) (a, b) = M.(~- a, b) | |
let ( / ) (a, b) (c, d) = M.(a * d, b * c) | |
let ( * ) (a, b) (c, d) = M.(a * c, b * d) | |
let to_string (a, b) = M.(to_string a ^ "/" ^ to_string b) | |
end | |
module IntRing : Ring = AddOfInt(Int) | |
module IntField : Field = AddOfInt(Int) | |
module FloatRing : Ring = AddOfInt(Float) | |
module FloatField : Field = AddOfInt(Float) | |
module IntRational : Field = AddOfInt(MakeRational(Int)) | |
module FloatRational : Field = AddOfInt(MakeRational(Float)) | |
let i = IntRational.(of_int 1 / of_int 2) | |
let f = FloatRational.(of_int 1 / of_int 2) |
Author
aur3l14no
commented
Jun 28, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment