https://github.com/octachron/rational_in_types
Type-level rational puzzles in OCaml
https://github.com/octachron/rational_in_types
ocaml phantom-types polymorphic-variants
Last synced: 3 months ago
JSON representation
Type-level rational puzzles in OCaml
- Host: GitHub
- URL: https://github.com/octachron/rational_in_types
- Owner: Octachron
- Created: 2016-06-08T20:51:58.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2016-06-08T21:18:11.000Z (about 10 years ago)
- Last Synced: 2025-05-01T14:41:54.542Z (about 1 year ago)
- Topics: ocaml, phantom-types, polymorphic-variants
- Language: OCaml
- Size: 22.5 KB
- Stars: 24
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
“ And with strange aeons, even types may multiply ”
This library is essentially a brain teaser, where types are twisted
and tortured for the sake of type-level arithmetic. Neither usability
nor sanity should be expected here.
Using and abusing polymorphic variants, this library implements all ring
operations over rational with fixed precision numerator and denominator at
the type level. Only 3 bits fixed-precision integers are implemented, it is
not clear how much further the OCaml compiler can be tortured by adding
more bits.
The integer representation used is quite simple:
The bit `0` and `1` are represented by
```OCaml
type 'a z = [ `_0 of 'a ]
type 'a o = [ `_1 of 'a ]
```
An integer `n` with three bits `n_0,n_1,n_2` is mapped to the object type
```
```
It is then possible to use polymorphic variant to implement any boolean
functions. A potential useful intermediary for humans is to implements
logical gates.
For instance, flipping a bit `'a` can be accomplished by the function
```OCaml
type ('a,'flip) flip = Flip
constraint
'a = [< `_0 of 'flip | `_1 of 'flip]
constraint
'table =
[<
| `_0 of [ `_1 of 'f]
| `_1 of [ `_0 of 'f]
]
constraint
'a = 'table
```
Note that the type of `'a` is consumed by the function flip and the result is
stored inside the type `'flip`. This implies that integer types can be used only
once in any type level computation. Fortunately, it is also possible to implements
a cloning function as
```OCaml
type ('a,'clone1,'clone2) cloner = Cloner
constraint
'a = [< `_0 of ( ('clone1 * 'clone2) as 't) | `_1 of 't]
constraint
'table = [< `_0 of 'b z * ' c z
| `_1 of 'b o * 'c o
]
constraint
'a = 'table
```
An adder gate goes one step further with three input and two outputs
```OCaml
type ('a,'b,'c, 'r, 'c_out) adder = Adder
(** Constraint on the inputs *)
constraint
'a = [< `_0 of 'b | `_1 of 'b ]
constraint
'b = [< `_0 of 'c | `_1 of 'c ]
constraint
'c = [< `_0 of ( 'r*'c_out as 't) | `_1 of 't ]
(** Logic table of the adder gate *)
constraint
'table =
[< `_0 of
[< `_0 of
[< `_0 of ('r2 z as 'r2_0) * ( 'c2 z as 'c2_0)
| `_1 of ( 'r2 o as 'r2_1) * 'c2_0 ]
| `_1 of
[< `_0 of 'r2_1 * 'c2_0
| `_1 of 'r2_0 * ('c2 o as 'c2_1) ]
]
| `_1 of
[< `_0 of
[< `_0 of 'r2_1 * 'c2_0
| `_1 of 'r2_0 * 'c2_1 ]
| `_1 of
[< `_0 of 'r2_0 * 'c2_1
| `_1 of 'r2_1 * 'c2_1 ]
]
]
constraint
'table = 'a
```