Skip to content

Commit

Permalink
ReasonML edition. (#247)
Browse files Browse the repository at this point in the history
* Reason edition: snippets chapter 1.1

* Reason edition: snippets chapter 1.2

* Reason edition: snippets chapter 1.3

* Reason edition: snippets chapter 1.4

* Reason edition: snippets chapter 1.5

* Reason edition: snippets chapter 1.6

* Reason edition: snippets chapter 1.7

* Reason edition: snippets chapter 1.8

* Reason edition: snippets chapter 1.9

* Reason edition: snippets chapter 1.10

* Reason edition: snippets chapter 2.1

* Reason edition: snippets chapter 2.2

* Reason edition: snippets chapter 2.3

* Reason edition: snippets chapter 2.4

* Reason edition: snippets chapter 2.5

* Reason edition: snippets chapter 2.6

* Reason edition: snippets chapter 3.2

* Reason edition: snippets chapter 3.3

* Reason edition: snippets chapter 3.4

* Reason edition: snippets chapter 3.6

* Reason edition: snippets chapter 3.7

* Reason edition: snippets chapter 3.8

* Reason edition: snippets chapter 3.9

* Reason edition: snippets chapter 3.10

* Reason edition: snippets chapter 3.11

* Reason edition: snippets chapter 3.14

* Reason edition: tex files, makefile, logo & colors.

* Reason edition: snippets chapter 3.5

* Obey horizontal space restrictions in Reason snippets.

* Add reason to gh workflows
  • Loading branch information
fhammerschmidt authored Sep 9, 2020
1 parent 7604f40 commit 8336698
Show file tree
Hide file tree
Showing 488 changed files with 2,339 additions and 4 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ jobs:
output: ctfp-reader-ocaml.pdf
- input: ctfp-print-ocaml.tex
output: ctfp-print-ocaml.pdf
- input: ctfp-reader-reason.tex
output: ctfp-reader-reason.pdf
- input: ctfp-print-reason.tex
output: ctfp-print-reason.pdf

steps:
- name: Set up Git repository
Expand Down Expand Up @@ -97,6 +101,10 @@ jobs:
destination: category-theory-for-programmers--print--ocaml--
- source: ctfp-reader-ocaml.pdf
destination: category-theory-for-programmers--reader--ocaml--
- source: ctfp-print-reason.pdf
destination: category-theory-for-programmers--print--reason--
- source: ctfp-reader-reason.pdf
destination: category-theory-for-programmers--reader--reason--
steps:
- name: Download build assets (${{ matrix.assets.source }})
uses: actions/download-artifact@v2
Expand Down
14 changes: 11 additions & 3 deletions src/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Igal Tabachnik, 2007.
# Based on work by Andres Raba et al., 2013-2015.

.PHONY: default all clean out-dir version.tex scala ocaml
.PHONY: default all clean out-dir version.tex scala ocaml reason

DIR := $(shell pwd)
GIT_VER := $(shell git describe --tags --always --long | tr -d '\n')
Expand All @@ -16,8 +16,10 @@ SCALATEXFILES = ctfp-reader-scala.tex ctfp-print-scala.tex # todo make this a ma

OCAMLTEXFILES = ctfp-reader-ocaml.tex ctfp-print-ocaml.tex # todo make this a macro

REASONTEXFILES = ctfp-reader-reason.tex ctfp-print-reason.tex # todo make this a macro

# Top-level LaTeX files from which CTFP book can be generated
TOPTEXFILES = version.tex $(DEFAULTTOPTEX) $(SCALATEXFILES) $(OCAMLTEXFILES)
TOPTEXFILES = version.tex $(DEFAULTTOPTEX) $(SCALATEXFILES) $(OCAMLTEXFILES) $(REASONTEXFILES)

# Default PDF file to make
DEFAULTPDF:=$(DEFAULTTOPTEX:.tex=.pdf)
Expand All @@ -28,6 +30,9 @@ SCALAPDF:=$(SCALATEXFILES:.tex=.pdf)
# OCaml PDF file to make
OCAMLPDF:=$(OCAMLTEXFILES:.tex=.pdf)

# ReasonML PDF file to make
REASONPDF:=$(REASONTEXFILES:.tex=.pdf)

# Other PDF files for the CTFP book
TOPPDFFILES:=$(TOPTEXFILES:.tex=.pdf)

Expand All @@ -37,7 +42,7 @@ OPTFILES = opt-print-ustrade.tex \
opt-scala.tex

# All the LaTeX files for the CTFP book in order of dependency
TEXFILES = $(TOPTEXFILES) $(SCALATEXFILES) $(OCAMLTEXFILES) $(OPTFILES)
TEXFILES = $(TOPTEXFILES) $(SCALATEXFILES) $(OCAMLTEXFILES) $(REASONTEXFILES) $(OPTFILES)

default: suffix=''
default: out-dir $(DEFAULTPDF) # todo cover
Expand All @@ -50,6 +55,9 @@ scala: clean out-dir version.tex $(SCALAPDF)
ocaml: suffix='-ocaml'
ocaml: clean out-dir version.tex $(OCAMLPDF)

reason: suffix='-reason'
reason: clean out-dir version.tex $(REASONPDF)

# Main targets
$(TOPPDFFILES) : %.pdf : %.tex $(TEXFILES)
if which latexmk > /dev/null 2>&1 ;\
Expand Down
6 changes: 6 additions & 0 deletions src/content/1.1/code/reason/snippet01.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module type Polymorphic_Function_F = {
type a;
type b;

let f: a => b;
};
6 changes: 6 additions & 0 deletions src/content/1.1/code/reason/snippet02.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module type Polymorphic_Function_G = {
type b;
type c;

let g: b => c;
};
10 changes: 10 additions & 0 deletions src/content/1.1/code/reason/snippet03.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Compose_Example =
(
F: Polymorphic_Function_F,
G: Polymorphic_Function_G with type b = F.b,
) => {
/** ReasonML doesn't have a compose operator. So, creating one. **/
let (>>) = (g, f, x) => g(f(x));

let compose: 'a => 'c = (G.g >> F.f: 'a => 'c);
};
19 changes: 19 additions & 0 deletions src/content/1.1/code/reason/snippet04.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Compose_Three_GF =
(
F: Polymorphic_Function_F,
G: Polymorphic_Function_G with type b = F.b,
H: Polymorphic_Function_H with type c = G.c,
) => {
let compose: 'a => 'd = H.h >> (G.g >> F.f);
};

module Compose_Three_HG =
(
F: Polymorphic_Function_F,
G: Polymorphic_Function_G with type b = F.b,
H: Polymorphic_Function_H with type c = G.c,
) => {
let compose: 'a => 'd = H.h >> G.g >> F.f;
};

Compose_Three_GF.compose == Compose_Three_HG.compose
1 change: 1 addition & 0 deletions src/content/1.1/code/reason/snippet05.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let id = x => x;
2 changes: 2 additions & 0 deletions src/content/1.1/code/reason/snippet06.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
f >> id;
id >> f;
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet01.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let alpha: 'a . f('a) => g('a);
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet02.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let alpha: f('a) => g('a);
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet03.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let alpha: f('a) => g('a);
4 changes: 4 additions & 0 deletions src/content/1.10/code/reason/snippet04.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let safe_head =
fun
| [] => None
| [x, ...xs] => Some(x);
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet05.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
compose(fmap(f), safe_head) == compose(safe_head, fmap(f));
2 changes: 2 additions & 0 deletions src/content/1.10/code/reason/snippet06.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* Starting with empty list */
let fmap = (f, safe_head([])) == fmap(f, None) == None;
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet07.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let safe_head = (fmap, f, []) == safe_head([]) == None;
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet08.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let fmap = (f, safe_head([x, ... xs])) == fmap(f(Some(x))) == Some(f(x));
2 changes: 2 additions & 0 deletions src/content/1.10/code/reason/snippet09.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let safe_head =
(fmap([x, ...xs])) == safe_head(f([x, ... xs])) == Some(f(x));
4 changes: 4 additions & 0 deletions src/content/1.10/code/reason/snippet10.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let rec fmap = f =>
fun
| [] => []
| [x, ...xs] => [f(x), ...fmap(f, xs)];
4 changes: 4 additions & 0 deletions src/content/1.10/code/reason/snippet11.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let rec fmap = f =>
fun
| None => None
| Some(x) => Some(f(x));
11 changes: 11 additions & 0 deletions src/content/1.10/code/reason/snippet12.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* ReasonML requires mutually recursive functions
* to be defined together */
let rec length: list('a) => const(int, 'a) = (
fun
| [] => Const(0)
| [_, ...xs] => Const(1 + un_const(length(xs))):
list('a) => const(int, 'a)
)
and un_const: 'c 'a. const('c, 'a) => 'c =
fun
| Const(c) => c;
3 changes: 3 additions & 0 deletions src/content/1.10/code/reason/snippet13.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
let un_const: 'c 'a. const('c, 'a) => 'c =
fun
| Const(c) => c;
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet14.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let length: list('a) => int;
3 changes: 3 additions & 0 deletions src/content/1.10/code/reason/snippet15.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
let scam: 'a. const('int, 'a) => option('a) =
fun
| Const(a) => None;
2 changes: 2 additions & 0 deletions src/content/1.10/code/reason/snippet16.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type reader('e, 'a) =
| Reader('e => 'a);
8 changes: 8 additions & 0 deletions src/content/1.10/code/reason/snippet17.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Reader_Functor = (T: {type e;}) : Functor => {
type t('a) = reader(T.e, 'a);

let fmap: 'a 'b. ('a => 'b, t('a)) => t('b) =
f =>
fun
| Reader(r) => Reader(compose(f, r));
};
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet18.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let alpha: reader(unit, 'a) => option('a);
3 changes: 3 additions & 0 deletions src/content/1.10/code/reason/snippet19.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
let dumb: 'a. reader(unit, 'a) => option('a) =
fun
| Reader(_) => None;
3 changes: 3 additions & 0 deletions src/content/1.10/code/reason/snippet20.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
let obvious: 'a. reader(unit, 'a) => option('a) =
fun
| Reader(f) => Some(f());
2 changes: 2 additions & 0 deletions src/content/1.10/code/reason/snippet21.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type op('r, 'a) =
| Op('a => 'r);
8 changes: 8 additions & 0 deletions src/content/1.10/code/reason/snippet22.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Op_Contravariant = (T: {type r;}) : Contravariant => {
type t('a) = op(T.r, 'a);

let contramap: ('b => 'a, t('a)) => t('b) =
f =>
fun
| Op(g) => Op(compose(g, f));
};
3 changes: 3 additions & 0 deletions src/content/1.10/code/reason/snippet23.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
let pred_to_str =
fun
| Op(f) => Op(x => (f(x)) ? "T" : "F");
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet24.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
compose(contramap(f), pred_to_str) == compose(pred_to_str, contramap(f));
5 changes: 5 additions & 0 deletions src/content/1.10/code/reason/snippet25.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Op_Bool = Op_Contravariant({type r = bool;});

let op_bool_contramap: ('b => 'a, Op_Bool.t('a)) => Op_Bool.t('b) = (
Op_Bool.contramap: ('b => 'a, Op_Bool.t('a)) => Op_Bool.t('b)
);
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet26.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'a => 'a
1 change: 1 addition & 0 deletions src/content/1.10/code/reason/snippet27.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
('a => 'a) => f('a)
1 change: 1 addition & 0 deletions src/content/1.2/code/reason/snippet01.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module type Chapter2_DeclareVariable = {let x: int;};
1 change: 1 addition & 0 deletions src/content/1.2/code/reason/snippet010.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let unit = _ => ();
3 changes: 3 additions & 0 deletions src/content/1.2/code/reason/snippet011.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type bool =
| false
| true;
1 change: 1 addition & 0 deletions src/content/1.2/code/reason/snippet02.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module type Chapter2_DeclareFunction = {let f: bool => bool;};
3 changes: 3 additions & 0 deletions src/content/1.2/code/reason/snippet03.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Chapter2_Bottom: Chapter2_DeclareFunction = {
let f = (b: bool): bool => failwith("Not Implemented");
};
3 changes: 3 additions & 0 deletions src/content/1.2/code/reason/snippet04.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Chapter2_Bottom: Chapter2_DeclareFunction = {
let f: bool => bool = _ => failwith("Not implemented");
};
1 change: 1 addition & 0 deletions src/content/1.2/code/reason/snippet05.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let fact = n => List.fold(List.range(1, n), ~init=1, ~f=( * ));
3 changes: 3 additions & 0 deletions src/content/1.2/code/reason/snippet06.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type void;

let rec absurd = (x: void) => absurd(x);
1 change: 1 addition & 0 deletions src/content/1.2/code/reason/snippet07.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let f44 = (): int => 44;
1 change: 1 addition & 0 deletions src/content/1.2/code/reason/snippet08.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let f_int = (x: int) => ();
1 change: 1 addition & 0 deletions src/content/1.2/code/reason/snippet09.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let f_int = (_: int) => ();
1 change: 1 addition & 0 deletions src/content/1.2/code/reason/snippet10.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let unit = _ => ();
3 changes: 3 additions & 0 deletions src/content/1.2/code/reason/snippet11.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type bool =
| false
| true;
6 changes: 6 additions & 0 deletions src/content/1.3/code/reason/snippet01.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module type Monoid = {
type a;

let mempty: a;
let mappend: (a, a) => a;
};
6 changes: 6 additions & 0 deletions src/content/1.3/code/reason/snippet02.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module StringMonoid: Monoid = {
type a = string;

let mempty = "";
let mappend = (++);
};
1 change: 1 addition & 0 deletions src/content/1.4/code/reason/snippet01.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type writer('a) = ('a, string);
1 change: 1 addition & 0 deletions src/content/1.4/code/reason/snippet02.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'a => writer('b)
7 changes: 7 additions & 0 deletions src/content/1.4/code/reason/snippet03.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module type Kleisli = {
type a;
type b;
type c;

let (>=>): (a => writer(b), b => writer(c), a) => writer(c);
};
1 change: 1 addition & 0 deletions src/content/1.4/code/reason/snippet04.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let pure = x => (x, "");
2 changes: 2 additions & 0 deletions src/content/1.4/code/reason/snippet05.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let up_case: string => writer(string) =
s => (String.uppercase(s), "up_case ");
4 changes: 4 additions & 0 deletions src/content/1.4/code/reason/snippet06.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let to_words: string => writer(list(string)) = (
s => (String.split(s, ~on=' '), "to_words "):
string => writer(list(string))
);
10 changes: 10 additions & 0 deletions src/content/1.4/code/reason/snippet07.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module KleisiExample =
(K: Kleisli
with type a = string
and type b = string
and type c = list(string)
) => {
let up_case_and_to_words: string => writer(list(string)) = (
K.(>=>)(up_case, to_words): string => writer(list(string))
);
};
3 changes: 3 additions & 0 deletions src/content/1.5/code/reason/snippet01.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type void; /* Uninhabited type */

type absurd = void => 'a = ;
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet02.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let unit = x => ();
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet03.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let yes = _ => true;
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet04.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let no = _ => false;
2 changes: 2 additions & 0 deletions src/content/1.5/code/reason/snippet05.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compose(f, g) == id;
compose(g, f) == id;
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet06.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let fst = ((a, b)) => a;
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet07.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let snd = ((a, b)) => b;
2 changes: 2 additions & 0 deletions src/content/1.5/code/reason/snippet08.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let fst = ((a, _)) => a;
let snd = ((_, b)) => b;
8 changes: 8 additions & 0 deletions src/content/1.5/code/reason/snippet09.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module type Chapter5_Product = {
type a;
type c;
type b;

let p: c => a;
let q: c => b;
};
12 changes: 12 additions & 0 deletions src/content/1.5/code/reason/snippet10.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Chapter5_Product_Example:
Chapter5_Product
with type a = int
and type b = bool
and type c = int = {
type a = int;
type b = bool;
type c = int;

let p = x => x;
let q = _ => true;
};
8 changes: 8 additions & 0 deletions src/content/1.5/code/reason/snippet11.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Chapter5_Product_Example2: Chapter5_Product = {
type a = int;
type b = bool;
type c = (int, int, bool);

let p = ((x, _, _)) => x;
let q = ((_, _, b)) => b;
};
2 changes: 2 additions & 0 deletions src/content/1.5/code/reason/snippet12.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let p' = compose(Chapter5_Product_Example.p, m);
let q' = compose(Chapter5_Product_Example.q, m);
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet13.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let m = (x: int) => (x, true);
2 changes: 2 additions & 0 deletions src/content/1.5/code/reason/snippet14.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let p = x => fst(m(x));
let q = x => snd(m(x));
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet15.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let m = ((x, _, b): (int, int, bool)) => (x, b);
2 changes: 2 additions & 0 deletions src/content/1.5/code/reason/snippet16.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fst == compose(p, m');
snd == compose(q, m');
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet17.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let m' = ((x, b): (int, bool)) => (x, x, b);
1 change: 1 addition & 0 deletions src/content/1.5/code/reason/snippet18.re
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let m' = ((x, b): (int, bool)) => (x, 42, b);
8 changes: 8 additions & 0 deletions src/content/1.5/code/reason/snippet19.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module type Chapter5_product_projection_example =
(Product: Chapter5_Product) => {
let m: Product.c => (Product.a, Product.b);
};

module ProjectionImpl = (Product: Chapter5_Product) => {
let m = c => (Product.p(c), Product.q(c));
};
Loading

0 comments on commit 8336698

Please sign in to comment.