Starting with a fragmentary understanding of ocaml I build an ocaml version of the division algebras. I keep the Scheme pattern where an algebra is a value bound to an identifier but in OCaml such values are called ‘modules’, are static and completed upon compilation. The mathematical ideas are in the Scheme development and not here. An algebra is roughly what an ocaml ‘module’ is for. Module names (as in “Xx” from “module Xx = struct end;;”) are in a special static space however. The Scheme version creates the new types dynamically whereas Ocaml can create them only at compile time but that is not a practical problem in the case at hand. I would like to see other applications of the Ocaml functor.

I try to do reals as reals from the division algebras.

```(define reals (list
(lambda (x) x) rr
0 zero? 1 + - *
(lambda (x) (/ x))))```
where rr is a random real generating function.
```module Reals = struct
type kind = float
let conj x : float = x
let zero = 0.
let one = 1.
let zeroQ x = x = 0.
let (+) = (+.)
let (-) = (-.)
let ( * ) = ( *.)
let inv x = 1. /. x
end
```
This definition yields the signature:
```module Reals :
sig
type kind = float
val zero : float
val conj : float -> float
val one : float
val zeroQ : float -> bool
val ( + ) : float -> float -> float
val ( - ) : float -> float -> float
val ( * ) : float -> float -> float
val inv : float -> float
end
```
But we want a signature that hides the fact that the values are floats; which isn’t so for higher algebras. If we hide that we will need a conversion to strings so we can see our computed results.
```module Reals : sig
type kind
val conj : kind -> kind
val zero : kind
val one : kind
val zeroQ : kind -> bool
val (+) : kind -> kind -> kind
val (-) : kind -> kind -> kind
val ( * ) : kind -> kind -> kind
val inv : kind -> kind
val str : kind -> string
end = struct
type kind = float
let zero = 0.
let conj x = x
let one = 1.
let zeroQ x = x = 0.
let (+) = (+.)
let (-) = (-.)
let ( * ) = ( *.)
let inv x = 1. /. x
let str = string_of_float
end```
Behold:
```Reals.str (Reals.(+) Reals.one Reals.one);;
- : string = "2."
```
Now we try to build a type from a type dynamically. We need to specify a shape that each of the division algebras will have in common. Maybe ocaml is good enough to infer this but for now we will give it explicitly. We need a module type for this shape which we will call “DivAlgebra”. All of the sample ocaml above code was provisional; together the following sample code runs.
```module type DivAlgebra = sig
type kind
val conj : kind -> kind
val zero : kind
val one : kind
val zeroQ : kind -> bool
val (+) : kind -> kind -> kind
val (-) : kind -> kind -> kind
val ( * ) : kind -> kind -> kind
val inv : kind -> kind
val str : kind -> string
end;;```
The Reals that we defined above are already trimmed down; we abstracted away the concrete properties such as the fact that they are built from floats. To minimize the eventual program source we undo that abstraction and define the BareReals as
```module BareReals = struct
type kind = float
let conj x = x
let zero = 0.
let one = 1.
let zeroQ x = x = 0.
let (+) = (+.)
let (-) = (-.)
let ( * ) = ( *.)
let inv x = 1. /. x
let str = string_of_float
end;;```
and instead build the Reals as merely
`module Reals = (BareReals : DivAlgebra);;`
The only point of the above line of code is to verify that our module BareReals actually conforms to the module type DivAlgebra. Now we attempt the process of building the function, which Ocaml calls a ‘Functor’ that goes from a DivAlgebra to the next higher DivAlgebra.
```module G = functor (Alg: DivAlgebra) -> struct
type kind = {r: Alg.kind; i: Alg.kind}
let conj x = {r = Alg.conj x.r; i = Alg.(-) Alg.zero x.i}
let zero = {r = Alg.zero; i = Alg.zero}
let one  = {r = Alg.one;  i = Alg.zero}
let zeroQ x = Alg.zeroQ x.r & Alg.zeroQ x.i
let (+) x y = {r = Alg.(+) x.r y.r; i = Alg.(+) x.i y.i}
let (-) x y = {r = Alg.(-) x.r y.r; i = Alg.(-) x.i y.i}
let ( * ) x y = {r = Alg.(-) (Alg.( * ) x.r y.r) (Alg.( * ) (Alg.conj x.i) y.i);
i = Alg.(+) (Alg.( * ) x.r y.i) (Alg.( * ) x.i y.r)}
let inv x = let d = Alg.inv (Alg.(+) (Alg.( * ) x.r (Alg.conj x.r))
(Alg.( * ) x.i (Alg.conj x.i)))
in {r = Alg.( * ) d (Alg.conj x.r); i = Alg.(-) Alg.zero
(Alg.( * ) d x.i)}
let str x = Alg.str x.r ^ ", " ^ Alg.str x.i
end;;
```
Now the functor G should take an algebra and return the next algebra.
`module Complex = G(Reals);;`
Thence:
```Complex.str (Complex.(+) Complex.one Complex.one);;
- : string = "2., 0."
```
and
`module Quaternion = G(G(Reals));;`
Thence:
```Quaternion.str (Quaternion.(+) Quaternion.one Quaternion.one);;
- : string = "2., 0., 0., 0."
```
The definition of G can be abbreviated to
```module G = functor (Alg: DivAlgebra) -> struct
open Alg
type kind = {r: Alg.kind; i: Alg.kind}
let conj x = {r = conj x.r; i = (-) zero x.i}
and zero = {r = zero; i = zero}
and one  = {r = one;  i = zero}
and zeroQ x = zeroQ x.r & zeroQ x.i
and (+) x y = {r = x.r + y.r; i = x.i + y.i}
and (-) x y = {r = x.r - y.r; i = x.i - y.i}
and ( * ) x y = {r = x.r * y.r - (conj x.i) * y.i;
i = x.r * y.i + x.i * y.r}
and inv x = let d = inv (x.r * (conj x.r) + x.i * (conj x.i))
in {r = d * (conj x.r); i = zero - d * x.i}
and str x = str x.r ^ ", " ^ str x.i
end;;```
The text “open Alg” allows us to omit many instances of “Alg.”. Ocaml’s style of value definition is not recursive but that for types is. That is why the “Alg.”s are still necessary in the definition of kind.
just the code, and plus input, plus testing. See comparison with Scheme code.