From 0e7932001cf78486a8bd4bb226a61fd98bedbe3e Mon Sep 17 00:00:00 2001 From: Arulselvan Madhavan <7578919+ArulselvanMadhavan@users.noreply.github.com> Date: Fri, 14 Feb 2020 08:52:21 -0800 Subject: [PATCH] OCaml version of CTFP (#201) * OCaml version of the book upto chapter 24 * Checking in Chapter 25 * Adding Ch 26 * Add final two chapters * Add Marcello Seri's comments * Ch 25 changes * Ch 26 * Run formatter * Adding OCaml tweaks in the half-title + colophon * Adding links in the colophon Co-authored-by: Igal Tabachnik --- src/Makefile | 18 +++++-- src/content/1.1/code/ocaml/snippet01.ml | 6 +++ src/content/1.1/code/ocaml/snippet02.ml | 6 +++ src/content/1.1/code/ocaml/snippet03.ml | 9 ++++ src/content/1.1/code/ocaml/snippet04.ml | 9 ++++ src/content/1.1/code/ocaml/snippet05.ml | 1 + src/content/1.1/code/ocaml/snippet06.ml | 2 + src/content/1.10/code/ocaml/snippet01.ml | 1 + src/content/1.10/code/ocaml/snippet02.ml | 1 + src/content/1.10/code/ocaml/snippet03.ml | 1 + src/content/1.10/code/ocaml/snippet04.ml | 4 ++ src/content/1.10/code/ocaml/snippet05.ml | 1 + src/content/1.10/code/ocaml/snippet06.ml | 2 + src/content/1.10/code/ocaml/snippet07.ml | 1 + src/content/1.10/code/ocaml/snippet08.ml | 1 + src/content/1.10/code/ocaml/snippet09.ml | 1 + src/content/1.10/code/ocaml/snippet10.ml | 4 ++ src/content/1.10/code/ocaml/snippet11.ml | 4 ++ src/content/1.10/code/ocaml/snippet12.ml | 8 +++ src/content/1.10/code/ocaml/snippet13.ml | 3 ++ src/content/1.10/code/ocaml/snippet14.ml | 1 + src/content/1.10/code/ocaml/snippet15.ml | 3 ++ src/content/1.10/code/ocaml/snippet16.ml | 1 + src/content/1.10/code/ocaml/snippet17.ml | 10 ++++ src/content/1.10/code/ocaml/snippet18.ml | 1 + src/content/1.10/code/ocaml/snippet19.ml | 3 ++ src/content/1.10/code/ocaml/snippet20.ml | 3 ++ src/content/1.10/code/ocaml/snippet21.ml | 1 + src/content/1.10/code/ocaml/snippet22.ml | 10 ++++ src/content/1.10/code/ocaml/snippet23.ml | 3 ++ src/content/1.10/code/ocaml/snippet24.ml | 1 + src/content/1.10/code/ocaml/snippet25.ml | 7 +++ src/content/1.10/code/ocaml/snippet26.ml | 1 + src/content/1.10/code/ocaml/snippet27.ml | 1 + src/content/1.2/code/ocaml/snippet01.ml | 3 ++ src/content/1.2/code/ocaml/snippet010.ml | 1 + src/content/1.2/code/ocaml/snippet011.ml | 3 ++ src/content/1.2/code/ocaml/snippet02.ml | 3 ++ src/content/1.2/code/ocaml/snippet03.ml | 3 ++ src/content/1.2/code/ocaml/snippet04.ml | 3 ++ src/content/1.2/code/ocaml/snippet05.ml | 1 + src/content/1.2/code/ocaml/snippet06.ml | 3 ++ src/content/1.2/code/ocaml/snippet07.ml | 1 + src/content/1.2/code/ocaml/snippet08.ml | 1 + src/content/1.2/code/ocaml/snippet09.ml | 1 + src/content/1.2/code/ocaml/snippet10.ml | 1 + src/content/1.2/code/ocaml/snippet11.ml | 3 ++ src/content/1.3/code/ocaml/snippet01.ml | 6 +++ src/content/1.3/code/ocaml/snippet02.ml | 6 +++ src/content/1.4/code/ocaml/snippet01.ml | 1 + src/content/1.4/code/ocaml/snippet02.ml | 1 + src/content/1.4/code/ocaml/snippet03.ml | 7 +++ src/content/1.4/code/ocaml/snippet04.ml | 1 + src/content/1.4/code/ocaml/snippet05.ml | 3 ++ src/content/1.4/code/ocaml/snippet06.ml | 3 ++ src/content/1.4/code/ocaml/snippet07.ml | 10 ++++ src/content/1.5/code/ocaml/snippet01.ml | 3 ++ src/content/1.5/code/ocaml/snippet02.ml | 1 + src/content/1.5/code/ocaml/snippet03.ml | 1 + src/content/1.5/code/ocaml/snippet04.ml | 1 + src/content/1.5/code/ocaml/snippet05.ml | 2 + src/content/1.5/code/ocaml/snippet06.ml | 1 + src/content/1.5/code/ocaml/snippet07.ml | 1 + src/content/1.5/code/ocaml/snippet08.ml | 2 + src/content/1.5/code/ocaml/snippet09.ml | 8 +++ src/content/1.5/code/ocaml/snippet10.ml | 12 +++++ src/content/1.5/code/ocaml/snippet11.ml | 8 +++ src/content/1.5/code/ocaml/snippet12.ml | 2 + src/content/1.5/code/ocaml/snippet13.ml | 1 + src/content/1.5/code/ocaml/snippet14.ml | 2 + src/content/1.5/code/ocaml/snippet15.ml | 1 + src/content/1.5/code/ocaml/snippet16.ml | 2 + src/content/1.5/code/ocaml/snippet17.ml | 1 + src/content/1.5/code/ocaml/snippet18.ml | 1 + src/content/1.5/code/ocaml/snippet19.ml | 9 ++++ src/content/1.5/code/ocaml/snippet20.ml | 11 ++++ src/content/1.5/code/ocaml/snippet21.ml | 8 +++ src/content/1.5/code/ocaml/snippet22.ml | 2 + src/content/1.5/code/ocaml/snippet23.ml | 3 ++ src/content/1.5/code/ocaml/snippet24.ml | 1 + src/content/1.5/code/ocaml/snippet25.ml | 3 ++ src/content/1.5/code/ocaml/snippet26.ml | 4 ++ src/content/1.5/code/ocaml/snippet27.ml | 2 + src/content/1.5/code/ocaml/snippet28.ml | 2 + src/content/1.6/code/ocaml/snippet01.ml | 1 + src/content/1.6/code/ocaml/snippet02.ml | 1 + src/content/1.6/code/ocaml/snippet03.ml | 1 + src/content/1.6/code/ocaml/snippet04.ml | 1 + src/content/1.6/code/ocaml/snippet05.ml | 1 + src/content/1.6/code/ocaml/snippet06.ml | 1 + src/content/1.6/code/ocaml/snippet07.ml | 1 + src/content/1.6/code/ocaml/snippet08.ml | 1 + src/content/1.6/code/ocaml/snippet09.ml | 1 + src/content/1.6/code/ocaml/snippet10.ml | 1 + src/content/1.6/code/ocaml/snippet11.ml | 1 + src/content/1.6/code/ocaml/snippet12.ml | 1 + src/content/1.6/code/ocaml/snippet13.ml | 1 + src/content/1.6/code/ocaml/snippet14.ml | 3 ++ src/content/1.6/code/ocaml/snippet15.ml | 5 ++ src/content/1.6/code/ocaml/snippet16.ml | 3 ++ src/content/1.6/code/ocaml/snippet17.ml | 3 ++ src/content/1.6/code/ocaml/snippet18.ml | 1 + src/content/1.6/code/ocaml/snippet19.ml | 3 ++ src/content/1.6/code/ocaml/snippet20.ml | 1 + src/content/1.6/code/ocaml/snippet21.ml | 3 ++ src/content/1.6/code/ocaml/snippet22.ml | 4 ++ src/content/1.6/code/ocaml/snippet23.ml | 1 + src/content/1.6/code/ocaml/snippet24.ml | 4 ++ src/content/1.6/code/ocaml/snippet25.ml | 3 ++ src/content/1.6/code/ocaml/snippet26.ml | 3 ++ src/content/1.6/code/ocaml/snippet27.ml | 1 + src/content/1.6/code/ocaml/snippet28.ml | 1 + src/content/1.6/code/ocaml/snippet29.ml | 1 + src/content/1.6/code/ocaml/snippet30.ml | 3 ++ src/content/1.6/code/ocaml/snippet31.ml | 8 +++ src/content/1.6/code/ocaml/snippet32.ml | 1 + src/content/1.6/code/ocaml/snippet33.ml | 1 + src/content/1.6/code/ocaml/snippet34.ml | 5 ++ src/content/1.6/code/ocaml/snippet35.ml | 4 ++ src/content/1.6/code/ocaml/snippet36.ml | 1 + src/content/1.6/code/ocaml/snippet37.ml | 3 ++ src/content/1.7/code/ocaml/snippet01.ml | 1 + src/content/1.7/code/ocaml/snippet02.ml | 3 ++ src/content/1.7/code/ocaml/snippet03.ml | 6 +++ src/content/1.7/code/ocaml/snippet04.ml | 4 ++ src/content/1.7/code/ocaml/snippet05.ml | 6 +++ src/content/1.7/code/ocaml/snippet06.ml | 6 +++ src/content/1.7/code/ocaml/snippet07.ml | 4 ++ src/content/1.7/code/ocaml/snippet08.ml | 1 + src/content/1.7/code/ocaml/snippet09.ml | 5 ++ src/content/1.7/code/ocaml/snippet10.ml | 8 +++ src/content/1.7/code/ocaml/snippet11.ml | 5 ++ src/content/1.7/code/ocaml/snippet12.ml | 1 + src/content/1.7/code/ocaml/snippet13.ml | 7 +++ src/content/1.7/code/ocaml/snippet14.ml | 5 ++ src/content/1.7/code/ocaml/snippet15.ml | 8 +++ src/content/1.7/code/ocaml/snippet16.ml | 3 ++ src/content/1.7/code/ocaml/snippet17.ml | 5 ++ src/content/1.7/code/ocaml/snippet18.ml | 3 ++ src/content/1.7/code/ocaml/snippet19.ml | 8 +++ src/content/1.7/code/ocaml/snippet20.ml | 1 + src/content/1.7/code/ocaml/snippet21.ml | 7 +++ src/content/1.7/code/ocaml/snippet22.ml | 3 ++ src/content/1.7/code/ocaml/snippet23.ml | 5 ++ src/content/1.7/code/ocaml/snippet24.ml | 1 + src/content/1.7/code/ocaml/snippet25.ml | 1 + src/content/1.7/code/ocaml/snippet26.ml | 1 + src/content/1.7/code/ocaml/snippet27.ml | 3 ++ src/content/1.7/code/ocaml/snippet28.ml | 5 ++ src/content/1.7/code/ocaml/snippet29.ml | 4 ++ src/content/1.7/code/ocaml/snippet30.ml | 3 ++ src/content/1.7/code/ocaml/snippet31.ml | 4 ++ src/content/1.7/code/ocaml/snippet32.ml | 5 ++ src/content/1.7/code/ocaml/snippet33.ml | 3 ++ src/content/1.7/code/ocaml/snippet34.ml | 1 + src/content/1.7/code/ocaml/snippet35.ml | 1 + src/content/1.8/code/ocaml/snippet01.ml | 28 ++++++++++ src/content/1.8/code/ocaml/snippet02.ml | 5 ++ src/content/1.8/code/ocaml/snippet03.ml | 5 ++ src/content/1.8/code/ocaml/snippet04.ml | 12 +++++ src/content/1.8/code/ocaml/snippet05.ml | 1 + src/content/1.8/code/ocaml/snippet06.ml | 5 ++ src/content/1.8/code/ocaml/snippet07.ml | 3 ++ src/content/1.8/code/ocaml/snippet08.ml | 9 ++++ src/content/1.8/code/ocaml/snippet09.ml | 14 +++++ src/content/1.8/code/ocaml/snippet10.ml | 10 ++++ src/content/1.8/code/ocaml/snippet11.ml | 1 + src/content/1.8/code/ocaml/snippet12.ml | 2 + src/content/1.8/code/ocaml/snippet13.ml | 1 + src/content/1.8/code/ocaml/snippet14.ml | 4 ++ src/content/1.8/code/ocaml/snippet15.ml | 8 +++ src/content/1.8/code/ocaml/snippet16.ml | 1 + src/content/1.8/code/ocaml/snippet17.ml | 10 ++++ src/content/1.8/code/ocaml/snippet18.ml | 3 ++ src/content/1.8/code/ocaml/snippet19.ml | 8 +++ src/content/1.8/code/ocaml/snippet20.ml | 6 +++ src/content/1.8/code/ocaml/snippet21.ml | 1 + src/content/1.8/code/ocaml/snippet22.ml | 7 +++ src/content/1.8/code/ocaml/snippet23.ml | 1 + src/content/1.8/code/ocaml/snippet24.ml | 1 + src/content/1.8/code/ocaml/snippet25.ml | 5 ++ src/content/1.8/code/ocaml/snippet26.ml | 7 +++ src/content/1.8/code/ocaml/snippet27.ml | 1 + src/content/1.8/code/ocaml/snippet28.ml | 3 ++ src/content/1.8/code/ocaml/snippet29.ml | 30 +++++++++++ src/content/1.8/code/ocaml/snippet30.ml | 12 +++++ src/content/1.9/code/ocaml/snippet01.ml | 1 + src/content/1.9/code/ocaml/snippet02.ml | 1 + src/content/1.9/code/ocaml/snippet03.ml | 1 + src/content/1.9/code/ocaml/snippet04.ml | 1 + src/content/1.9/code/ocaml/snippet05.ml | 1 + src/content/1.9/code/ocaml/snippet06.ml | 1 + src/content/1.9/code/ocaml/snippet07.ml | 1 + src/content/1.9/code/ocaml/snippet08.ml | 1 + src/content/1.9/code/ocaml/snippet09.ml | 1 + src/content/1.9/code/ocaml/snippet10.ml | 3 ++ src/content/1.9/code/ocaml/snippet11.ml | 9 ++++ src/content/1.9/code/ocaml/snippet12.ml | 1 + src/content/1.9/code/ocaml/snippet13.ml | 1 + src/content/1.9/code/ocaml/snippet14.ml | 1 + src/content/1.9/code/ocaml/snippet15.ml | 1 + src/content/2.1/code/ocaml/snippet01.ml | 2 + src/content/2.1/code/ocaml/snippet02.ml | 4 ++ src/content/2.2/code/ocaml/snippet01.ml | 2 + src/content/2.2/code/ocaml/snippet02.ml | 4 ++ src/content/2.2/code/ocaml/snippet03.ml | 2 + src/content/2.2/code/ocaml/snippet04.ml | 2 + src/content/2.2/code/ocaml/snippet05.ml | 2 + src/content/2.2/code/ocaml/snippet06.ml | 2 + src/content/2.2/code/ocaml/snippet07.ml | 2 + src/content/2.2/code/ocaml/snippet08.ml | 1 + src/content/2.2/code/ocaml/snippet09.ml | 2 + src/content/2.2/code/ocaml/snippet10.ml | 1 + src/content/2.2/code/ocaml/snippet11.ml | 1 + src/content/2.2/code/ocaml/snippet12.ml | 1 + src/content/2.2/code/ocaml/snippet13.ml | 2 + src/content/2.2/code/ocaml/snippet14.ml | 3 ++ src/content/2.2/code/ocaml/snippet15.ml | 1 + src/content/2.2/code/ocaml/snippet16.ml | 1 + src/content/2.2/code/ocaml/snippet17.ml | 13 +++++ src/content/2.2/code/ocaml/snippet18.ml | 1 + src/content/2.2/code/ocaml/snippet19.ml | 1 + src/content/2.3/code/ocaml/snippet01.ml | 6 +++ src/content/2.3/code/ocaml/snippet02.ml | 8 +++ src/content/2.3/code/ocaml/snippet03.ml | 2 + src/content/2.3/code/ocaml/snippet04.ml | 1 + src/content/2.3/code/ocaml/snippet05.ml | 1 + src/content/2.3/code/ocaml/snippet06.ml | 1 + src/content/2.3/code/ocaml/snippet07.ml | 6 +++ src/content/2.3/code/ocaml/snippet08.ml | 6 +++ src/content/2.3/code/ocaml/snippet09.ml | 1 + src/content/2.3/code/ocaml/snippet10.ml | 1 + src/content/2.4/code/ocaml/snippet01.ml | 1 + src/content/2.4/code/ocaml/snippet02.ml | 7 +++ src/content/2.4/code/ocaml/snippet03.ml | 1 + src/content/2.4/code/ocaml/snippet04.ml | 7 +++ src/content/2.4/code/ocaml/snippet05.ml | 7 +++ src/content/2.4/code/ocaml/snippet06.ml | 6 +++ src/content/2.4/code/ocaml/snippet07.ml | 1 + src/content/2.4/code/ocaml/snippet08.ml | 1 + src/content/2.4/code/ocaml/snippet09.ml | 6 +++ src/content/2.4/code/ocaml/snippet10.ml | 7 +++ src/content/2.4/code/ocaml/snippet11.ml | 1 + src/content/2.4/code/ocaml/snippet12.ml | 6 +++ src/content/2.4/code/ocaml/snippet13.ml | 7 +++ src/content/2.4/code/ocaml/snippet14.ml | 1 + src/content/2.4/code/ocaml/snippet15.ml | 10 ++++ src/content/2.5/code/ocaml/snippet01.ml | 1 + src/content/2.5/code/ocaml/snippet02.ml | 7 +++ src/content/2.5/code/ocaml/snippet03.ml | 6 +++ src/content/2.5/code/ocaml/snippet04.ml | 1 + src/content/2.5/code/ocaml/snippet05.ml | 1 + src/content/2.5/code/ocaml/snippet06.ml | 1 + src/content/2.5/code/ocaml/snippet07.ml | 1 + src/content/2.6/code/ocaml/snippet01.ml | 11 ++++ src/content/2.6/code/ocaml/snippet02.ml | 2 + src/content/3.10/code/ocaml/snippet01.ml | 13 +++++ src/content/3.10/code/ocaml/snippet02.ml | 1 + src/content/3.10/code/ocaml/snippet03.ml | 1 + src/content/3.10/code/ocaml/snippet04.ml | 4 ++ src/content/3.10/code/ocaml/snippet05.ml | 1 + src/content/3.10/code/ocaml/snippet06.ml | 2 + src/content/3.10/code/ocaml/snippet07.ml | 5 ++ src/content/3.10/code/ocaml/snippet08.ml | 5 ++ src/content/3.10/code/ocaml/snippet09.ml | 9 ++++ src/content/3.10/code/ocaml/snippet10.ml | 4 ++ src/content/3.10/code/ocaml/snippet11.ml | 4 ++ src/content/3.10/code/ocaml/snippet12.ml | 15 ++++++ src/content/3.10/code/ocaml/snippet13.ml | 4 ++ src/content/3.10/code/ocaml/snippet14.ml | 3 ++ src/content/3.10/code/ocaml/snippet15.ml | 8 +++ src/content/3.10/code/ocaml/snippet16.ml | 35 ++++++++++++ src/content/3.10/code/ocaml/snippet17.ml | 6 +++ src/content/3.10/code/ocaml/snippet18.ml | 7 +++ src/content/3.11/code/ocaml/snippet01.ml | 5 ++ src/content/3.11/code/ocaml/snippet02.ml | 1 + src/content/3.11/code/ocaml/snippet03.ml | 2 + src/content/3.11/code/ocaml/snippet04.ml | 10 ++++ src/content/3.11/code/ocaml/snippet05.ml | 29 ++++++++++ src/content/3.11/code/ocaml/snippet06.ml | 9 ++++ src/content/3.11/code/ocaml/snippet07.ml | 9 ++++ src/content/3.11/code/ocaml/snippet08.ml | 23 ++++++++ src/content/3.11/code/ocaml/snippet09.ml | 8 +++ src/content/3.11/code/ocaml/snippet10.ml | 23 ++++++++ src/content/3.11/code/ocaml/snippet11.ml | 6 +++ src/content/3.11/code/ocaml/snippet12.ml | 17 ++++++ src/content/3.14/code/ocaml/snippet01.ml | 5 ++ src/content/3.14/code/ocaml/snippet02.ml | 1 + src/content/3.14/code/ocaml/snippet03.ml | 1 + src/content/3.14/code/ocaml/snippet04.ml | 3 ++ src/content/3.2/code/ocaml/snippet01.ml | 1 + src/content/3.2/code/ocaml/snippet02.ml | 5 ++ src/content/3.2/code/ocaml/snippet03.ml | 5 ++ src/content/3.2/code/ocaml/snippet04.ml | 8 +++ src/content/3.2/code/ocaml/snippet05.ml | 7 +++ src/content/3.2/code/ocaml/snippet06.ml | 66 +++++++++++++++++++++++ src/content/3.2/code/ocaml/snippet07.ml | 1 + src/content/3.2/code/ocaml/snippet08.ml | 2 + src/content/3.2/code/ocaml/snippet09.ml | 1 + src/content/3.3/code/ocaml/snippet01.ml | 1 + src/content/3.3/code/ocaml/snippet02.ml | 2 + src/content/3.4/code/ocaml/snippet01.ml | 12 +++++ src/content/3.4/code/ocaml/snippet02.ml | 7 +++ src/content/3.4/code/ocaml/snippet03.ml | 1 + src/content/3.4/code/ocaml/snippet04.ml | 6 +++ src/content/3.4/code/ocaml/snippet05.ml | 12 +++++ src/content/3.4/code/ocaml/snippet06.ml | 1 + src/content/3.4/code/ocaml/snippet07.ml | 1 + src/content/3.4/code/ocaml/snippet08.ml | 3 ++ src/content/3.4/code/ocaml/snippet09.ml | 1 + src/content/3.4/code/ocaml/snippet10.ml | 6 +++ src/content/3.4/code/ocaml/snippet11.ml | 5 ++ src/content/3.4/code/ocaml/snippet12.ml | 1 + src/content/3.4/code/ocaml/snippet13.ml | 9 ++++ src/content/3.4/code/ocaml/snippet14.ml | 6 +++ src/content/3.4/code/ocaml/snippet15.ml | 3 ++ src/content/3.4/code/ocaml/snippet16.ml | 3 ++ src/content/3.4/code/ocaml/snippet17.ml | 7 +++ src/content/3.4/code/ocaml/snippet18.ml | 10 ++++ src/content/3.4/code/ocaml/snippet19.ml | 1 + src/content/3.4/code/ocaml/snippet20.ml | 5 ++ src/content/3.4/code/ocaml/snippet21.ml | 1 + src/content/3.4/code/ocaml/snippet22.ml | 12 +++++ src/content/3.4/code/ocaml/snippet23.ml | 10 ++++ src/content/3.4/code/ocaml/snippet24.ml | 3 ++ src/content/3.4/code/ocaml/snippet25.ml | 11 ++++ src/content/3.5/code/ocaml/snippet01.ml | 6 +++ src/content/3.5/code/ocaml/snippet02.ml | 1 + src/content/3.5/code/ocaml/snippet03.ml | 12 +++++ src/content/3.5/code/ocaml/snippet04.ml | 3 ++ src/content/3.5/code/ocaml/snippet05.ml | 13 +++++ src/content/3.5/code/ocaml/snippet06.ml | 1 + src/content/3.5/code/ocaml/snippet07.ml | 1 + src/content/3.5/code/ocaml/snippet08.ml | 1 + src/content/3.5/code/ocaml/snippet09.ml | 3 ++ src/content/3.5/code/ocaml/snippet10.ml | 4 ++ src/content/3.5/code/ocaml/snippet11.ml | 6 +++ src/content/3.5/code/ocaml/snippet12.ml | 10 ++++ src/content/3.5/code/ocaml/snippet13.ml | 1 + src/content/3.5/code/ocaml/snippet14.ml | 1 + src/content/3.5/code/ocaml/snippet15.ml | 9 ++++ src/content/3.5/code/ocaml/snippet16.ml | 1 + src/content/3.5/code/ocaml/snippet17.ml | 1 + src/content/3.5/code/ocaml/snippet18.ml | 6 +++ src/content/3.5/code/ocaml/snippet19.ml | 15 ++++++ src/content/3.5/code/ocaml/snippet20.ml | 1 + src/content/3.5/code/ocaml/snippet21.ml | 1 + src/content/3.5/code/ocaml/snippet22.ml | 10 ++++ src/content/3.5/code/ocaml/snippet23.ml | 1 + src/content/3.5/code/ocaml/snippet24.ml | 1 + src/content/3.5/code/ocaml/snippet25.ml | 5 ++ src/content/3.5/code/ocaml/snippet26.ml | 1 + src/content/3.5/code/ocaml/snippet27.ml | 1 + src/content/3.5/code/ocaml/snippet28.ml | 4 ++ src/content/3.5/code/ocaml/snippet29.ml | 10 ++++ src/content/3.5/code/ocaml/snippet30.ml | 6 +++ src/content/3.5/code/ocaml/snippet31.ml | 1 + src/content/3.5/code/ocaml/snippet32.ml | 1 + src/content/3.5/code/ocaml/snippet33.ml | 1 + src/content/3.5/code/ocaml/snippet34.ml | 1 + src/content/3.5/code/ocaml/snippet35.ml | 1 + src/content/3.5/code/ocaml/snippet36.ml | 1 + src/content/3.5/code/ocaml/snippet37.ml | 22 ++++++++ src/content/3.6/code/ocaml/snippet01.ml | 5 ++ src/content/3.6/code/ocaml/snippet02.ml | 3 ++ src/content/3.6/code/ocaml/snippet03.ml | 6 +++ src/content/3.6/code/ocaml/snippet04.ml | 1 + src/content/3.6/code/ocaml/snippet05.ml | 1 + src/content/3.6/code/ocaml/snippet06.ml | 1 + src/content/3.6/code/ocaml/snippet07.ml | 2 + src/content/3.6/code/ocaml/snippet08.ml | 2 + src/content/3.6/code/ocaml/snippet09.ml | 2 + src/content/3.6/code/ocaml/snippet10.ml | 2 + src/content/3.6/code/ocaml/snippet11.ml | 1 + src/content/3.6/code/ocaml/snippet12.ml | 2 + src/content/3.6/code/ocaml/snippet13.ml | 2 + src/content/3.6/code/ocaml/snippet14.ml | 4 ++ src/content/3.6/code/ocaml/snippet15.ml | 1 + src/content/3.6/code/ocaml/snippet16.ml | 1 + src/content/3.6/code/ocaml/snippet17.ml | 2 + src/content/3.6/code/ocaml/snippet18.ml | 1 + src/content/3.6/code/ocaml/snippet19.ml | 1 + src/content/3.6/code/ocaml/snippet20.ml | 1 + src/content/3.6/code/ocaml/snippet21.ml | 15 ++++++ src/content/3.6/code/ocaml/snippet22.ml | 1 + src/content/3.6/code/ocaml/snippet23.ml | 1 + src/content/3.6/code/ocaml/snippet24.ml | 2 + src/content/3.6/code/ocaml/snippet25.ml | 3 ++ src/content/3.7/code/ocaml/snippet01.ml | 1 + src/content/3.7/code/ocaml/snippet02.ml | 1 + src/content/3.7/code/ocaml/snippet03.ml | 5 ++ src/content/3.7/code/ocaml/snippet04.ml | 1 + src/content/3.7/code/ocaml/snippet05.ml | 8 +++ src/content/3.7/code/ocaml/snippet06.ml | 1 + src/content/3.7/code/ocaml/snippet07.ml | 1 + src/content/3.7/code/ocaml/snippet08.ml | 1 + src/content/3.7/code/ocaml/snippet09.ml | 5 ++ src/content/3.7/code/ocaml/snippet10.ml | 1 + src/content/3.7/code/ocaml/snippet11.ml | 5 ++ src/content/3.7/code/ocaml/snippet12.ml | 1 + src/content/3.7/code/ocaml/snippet13.ml | 13 +++++ src/content/3.7/code/ocaml/snippet14.ml | 1 + src/content/3.7/code/ocaml/snippet15.ml | 58 ++++++++++++++++++++ src/content/3.7/code/ocaml/snippet16.ml | 1 + src/content/3.7/code/ocaml/snippet17.ml | 8 +++ src/content/3.7/code/ocaml/snippet18.ml | 1 + src/content/3.7/code/ocaml/snippet19.ml | 3 ++ src/content/3.7/code/ocaml/snippet20.ml | 24 +++++++++ src/content/3.7/code/ocaml/snippet21.ml | 1 + src/content/3.7/code/ocaml/snippet22.ml | 3 ++ src/content/3.7/code/ocaml/snippet23.ml | 1 + src/content/3.7/code/ocaml/snippet24.ml | 1 + src/content/3.7/code/ocaml/snippet25.ml | 6 +++ src/content/3.7/code/ocaml/snippet26.ml | 1 + src/content/3.7/code/ocaml/snippet27.ml | 1 + src/content/3.7/code/ocaml/snippet28.ml | 11 ++++ src/content/3.7/code/ocaml/snippet29.ml | 5 ++ src/content/3.7/code/ocaml/snippet30.ml | 1 + src/content/3.7/code/ocaml/snippet31.ml | 1 + src/content/3.7/code/ocaml/snippet32.ml | 1 + src/content/3.7/code/ocaml/snippet33.ml | 1 + src/content/3.7/code/ocaml/snippet34.ml | 1 + src/content/3.7/code/ocaml/snippet35.ml | 1 + src/content/3.7/code/ocaml/snippet36.ml | 1 + src/content/3.7/code/ocaml/snippet37.ml | 28 ++++++++++ src/content/3.7/code/ocaml/snippet38.ml | 1 + src/content/3.7/code/ocaml/snippet39.ml | 2 + src/content/3.8/code/ocaml/snippet01.ml | 7 +++ src/content/3.8/code/ocaml/snippet02.ml | 3 ++ src/content/3.8/code/ocaml/snippet03.ml | 6 +++ src/content/3.8/code/ocaml/snippet04.ml | 13 +++++ src/content/3.8/code/ocaml/snippet05.ml | 6 +++ src/content/3.8/code/ocaml/snippet06.ml | 7 +++ src/content/3.8/code/ocaml/snippet07.ml | 1 + src/content/3.8/code/ocaml/snippet08.ml | 1 + src/content/3.8/code/ocaml/snippet09.ml | 1 + src/content/3.8/code/ocaml/snippet10.ml | 3 ++ src/content/3.8/code/ocaml/snippet11.ml | 3 ++ src/content/3.8/code/ocaml/snippet12.ml | 5 ++ src/content/3.8/code/ocaml/snippet13.ml | 5 ++ src/content/3.8/code/ocaml/snippet14.ml | 3 ++ src/content/3.8/code/ocaml/snippet15.ml | 3 ++ src/content/3.8/code/ocaml/snippet16.ml | 10 ++++ src/content/3.8/code/ocaml/snippet17.ml | 3 ++ src/content/3.8/code/ocaml/snippet18.ml | 4 ++ src/content/3.8/code/ocaml/snippet19.ml | 3 ++ src/content/3.8/code/ocaml/snippet20.ml | 3 ++ src/content/3.8/code/ocaml/snippet21.ml | 4 ++ src/content/3.8/code/ocaml/snippet22.ml | 1 + src/content/3.8/code/ocaml/snippet23.ml | 4 ++ src/content/3.8/code/ocaml/snippet24.ml | 1 + src/content/3.8/code/ocaml/snippet25.ml | 7 +++ src/content/3.8/code/ocaml/snippet26.ml | 11 ++++ src/content/3.8/code/ocaml/snippet27.ml | 1 + src/content/3.8/code/ocaml/snippet28.ml | 10 ++++ src/content/3.8/code/ocaml/snippet29.ml | 10 ++++ src/content/3.8/code/ocaml/snippet30.ml | 14 +++++ src/content/3.8/code/ocaml/snippet31.ml | 2 + src/content/3.8/code/ocaml/snippet32.ml | 2 + src/content/3.8/code/ocaml/snippet33.ml | 1 + src/content/3.8/code/ocaml/snippet34.ml | 1 + src/content/3.8/code/ocaml/snippet35.ml | 2 + src/content/3.9/code/ocaml/snippet01.ml | 2 + src/content/3.9/code/ocaml/snippet02.ml | 1 + src/content/3.9/code/ocaml/snippet03.ml | 4 ++ src/content/3.9/code/ocaml/snippet04.ml | 2 + src/content/3.9/code/ocaml/snippet05.ml | 3 ++ src/content/3.9/code/ocaml/snippet06.ml | 3 ++ src/content/3.9/code/ocaml/snippet07.ml | 1 + src/content/3.9/code/ocaml/snippet08.ml | 15 ++++++ src/content/3.9/code/ocaml/snippet09.ml | 8 +++ src/content/3.9/code/ocaml/snippet10.ml | 4 ++ src/content/3.9/code/ocaml/snippet11.ml | 2 + src/content/3.9/code/ocaml/snippet12.ml | 2 + src/content/3.9/code/ocaml/snippet13.ml | 4 ++ src/content/3.9/code/ocaml/snippet14.ml | 2 + src/content/3.9/code/ocaml/snippet15.ml | 2 + src/content/ocaml/colophon.tex | 2 + src/content/ocaml/editor-note.tex | 27 ++++++++++ src/ctfp-print-ocaml.tex | 3 ++ src/ctfp-reader-ocaml.tex | 3 ++ src/fig/icons/ocaml.png | Bin 0 -> 15789 bytes src/opt-ocaml.tex | 4 ++ 483 files changed, 2117 insertions(+), 5 deletions(-) create mode 100644 src/content/1.1/code/ocaml/snippet01.ml create mode 100644 src/content/1.1/code/ocaml/snippet02.ml create mode 100644 src/content/1.1/code/ocaml/snippet03.ml create mode 100644 src/content/1.1/code/ocaml/snippet04.ml create mode 100644 src/content/1.1/code/ocaml/snippet05.ml create mode 100644 src/content/1.1/code/ocaml/snippet06.ml create mode 100644 src/content/1.10/code/ocaml/snippet01.ml create mode 100644 src/content/1.10/code/ocaml/snippet02.ml create mode 100644 src/content/1.10/code/ocaml/snippet03.ml create mode 100644 src/content/1.10/code/ocaml/snippet04.ml create mode 100644 src/content/1.10/code/ocaml/snippet05.ml create mode 100644 src/content/1.10/code/ocaml/snippet06.ml create mode 100644 src/content/1.10/code/ocaml/snippet07.ml create mode 100644 src/content/1.10/code/ocaml/snippet08.ml create mode 100644 src/content/1.10/code/ocaml/snippet09.ml create mode 100644 src/content/1.10/code/ocaml/snippet10.ml create mode 100644 src/content/1.10/code/ocaml/snippet11.ml create mode 100644 src/content/1.10/code/ocaml/snippet12.ml create mode 100644 src/content/1.10/code/ocaml/snippet13.ml create mode 100644 src/content/1.10/code/ocaml/snippet14.ml create mode 100644 src/content/1.10/code/ocaml/snippet15.ml create mode 100644 src/content/1.10/code/ocaml/snippet16.ml create mode 100644 src/content/1.10/code/ocaml/snippet17.ml create mode 100644 src/content/1.10/code/ocaml/snippet18.ml create mode 100644 src/content/1.10/code/ocaml/snippet19.ml create mode 100644 src/content/1.10/code/ocaml/snippet20.ml create mode 100644 src/content/1.10/code/ocaml/snippet21.ml create mode 100644 src/content/1.10/code/ocaml/snippet22.ml create mode 100644 src/content/1.10/code/ocaml/snippet23.ml create mode 100644 src/content/1.10/code/ocaml/snippet24.ml create mode 100644 src/content/1.10/code/ocaml/snippet25.ml create mode 100644 src/content/1.10/code/ocaml/snippet26.ml create mode 100644 src/content/1.10/code/ocaml/snippet27.ml create mode 100644 src/content/1.2/code/ocaml/snippet01.ml create mode 100644 src/content/1.2/code/ocaml/snippet010.ml create mode 100644 src/content/1.2/code/ocaml/snippet011.ml create mode 100644 src/content/1.2/code/ocaml/snippet02.ml create mode 100644 src/content/1.2/code/ocaml/snippet03.ml create mode 100644 src/content/1.2/code/ocaml/snippet04.ml create mode 100644 src/content/1.2/code/ocaml/snippet05.ml create mode 100644 src/content/1.2/code/ocaml/snippet06.ml create mode 100644 src/content/1.2/code/ocaml/snippet07.ml create mode 100644 src/content/1.2/code/ocaml/snippet08.ml create mode 100644 src/content/1.2/code/ocaml/snippet09.ml create mode 100644 src/content/1.2/code/ocaml/snippet10.ml create mode 100644 src/content/1.2/code/ocaml/snippet11.ml create mode 100644 src/content/1.3/code/ocaml/snippet01.ml create mode 100644 src/content/1.3/code/ocaml/snippet02.ml create mode 100644 src/content/1.4/code/ocaml/snippet01.ml create mode 100644 src/content/1.4/code/ocaml/snippet02.ml create mode 100644 src/content/1.4/code/ocaml/snippet03.ml create mode 100644 src/content/1.4/code/ocaml/snippet04.ml create mode 100644 src/content/1.4/code/ocaml/snippet05.ml create mode 100644 src/content/1.4/code/ocaml/snippet06.ml create mode 100644 src/content/1.4/code/ocaml/snippet07.ml create mode 100644 src/content/1.5/code/ocaml/snippet01.ml create mode 100644 src/content/1.5/code/ocaml/snippet02.ml create mode 100644 src/content/1.5/code/ocaml/snippet03.ml create mode 100644 src/content/1.5/code/ocaml/snippet04.ml create mode 100644 src/content/1.5/code/ocaml/snippet05.ml create mode 100644 src/content/1.5/code/ocaml/snippet06.ml create mode 100644 src/content/1.5/code/ocaml/snippet07.ml create mode 100644 src/content/1.5/code/ocaml/snippet08.ml create mode 100644 src/content/1.5/code/ocaml/snippet09.ml create mode 100644 src/content/1.5/code/ocaml/snippet10.ml create mode 100644 src/content/1.5/code/ocaml/snippet11.ml create mode 100644 src/content/1.5/code/ocaml/snippet12.ml create mode 100644 src/content/1.5/code/ocaml/snippet13.ml create mode 100644 src/content/1.5/code/ocaml/snippet14.ml create mode 100644 src/content/1.5/code/ocaml/snippet15.ml create mode 100644 src/content/1.5/code/ocaml/snippet16.ml create mode 100644 src/content/1.5/code/ocaml/snippet17.ml create mode 100644 src/content/1.5/code/ocaml/snippet18.ml create mode 100644 src/content/1.5/code/ocaml/snippet19.ml create mode 100644 src/content/1.5/code/ocaml/snippet20.ml create mode 100644 src/content/1.5/code/ocaml/snippet21.ml create mode 100644 src/content/1.5/code/ocaml/snippet22.ml create mode 100644 src/content/1.5/code/ocaml/snippet23.ml create mode 100644 src/content/1.5/code/ocaml/snippet24.ml create mode 100644 src/content/1.5/code/ocaml/snippet25.ml create mode 100644 src/content/1.5/code/ocaml/snippet26.ml create mode 100644 src/content/1.5/code/ocaml/snippet27.ml create mode 100644 src/content/1.5/code/ocaml/snippet28.ml create mode 100644 src/content/1.6/code/ocaml/snippet01.ml create mode 100644 src/content/1.6/code/ocaml/snippet02.ml create mode 100644 src/content/1.6/code/ocaml/snippet03.ml create mode 100644 src/content/1.6/code/ocaml/snippet04.ml create mode 100644 src/content/1.6/code/ocaml/snippet05.ml create mode 100644 src/content/1.6/code/ocaml/snippet06.ml create mode 100644 src/content/1.6/code/ocaml/snippet07.ml create mode 100644 src/content/1.6/code/ocaml/snippet08.ml create mode 100644 src/content/1.6/code/ocaml/snippet09.ml create mode 100644 src/content/1.6/code/ocaml/snippet10.ml create mode 100644 src/content/1.6/code/ocaml/snippet11.ml create mode 100644 src/content/1.6/code/ocaml/snippet12.ml create mode 100644 src/content/1.6/code/ocaml/snippet13.ml create mode 100644 src/content/1.6/code/ocaml/snippet14.ml create mode 100644 src/content/1.6/code/ocaml/snippet15.ml create mode 100644 src/content/1.6/code/ocaml/snippet16.ml create mode 100644 src/content/1.6/code/ocaml/snippet17.ml create mode 100644 src/content/1.6/code/ocaml/snippet18.ml create mode 100644 src/content/1.6/code/ocaml/snippet19.ml create mode 100644 src/content/1.6/code/ocaml/snippet20.ml create mode 100644 src/content/1.6/code/ocaml/snippet21.ml create mode 100644 src/content/1.6/code/ocaml/snippet22.ml create mode 100644 src/content/1.6/code/ocaml/snippet23.ml create mode 100644 src/content/1.6/code/ocaml/snippet24.ml create mode 100644 src/content/1.6/code/ocaml/snippet25.ml create mode 100644 src/content/1.6/code/ocaml/snippet26.ml create mode 100644 src/content/1.6/code/ocaml/snippet27.ml create mode 100644 src/content/1.6/code/ocaml/snippet28.ml create mode 100644 src/content/1.6/code/ocaml/snippet29.ml create mode 100644 src/content/1.6/code/ocaml/snippet30.ml create mode 100644 src/content/1.6/code/ocaml/snippet31.ml create mode 100644 src/content/1.6/code/ocaml/snippet32.ml create mode 100644 src/content/1.6/code/ocaml/snippet33.ml create mode 100644 src/content/1.6/code/ocaml/snippet34.ml create mode 100644 src/content/1.6/code/ocaml/snippet35.ml create mode 100644 src/content/1.6/code/ocaml/snippet36.ml create mode 100644 src/content/1.6/code/ocaml/snippet37.ml create mode 100644 src/content/1.7/code/ocaml/snippet01.ml create mode 100644 src/content/1.7/code/ocaml/snippet02.ml create mode 100644 src/content/1.7/code/ocaml/snippet03.ml create mode 100644 src/content/1.7/code/ocaml/snippet04.ml create mode 100644 src/content/1.7/code/ocaml/snippet05.ml create mode 100644 src/content/1.7/code/ocaml/snippet06.ml create mode 100644 src/content/1.7/code/ocaml/snippet07.ml create mode 100644 src/content/1.7/code/ocaml/snippet08.ml create mode 100644 src/content/1.7/code/ocaml/snippet09.ml create mode 100644 src/content/1.7/code/ocaml/snippet10.ml create mode 100644 src/content/1.7/code/ocaml/snippet11.ml create mode 100644 src/content/1.7/code/ocaml/snippet12.ml create mode 100644 src/content/1.7/code/ocaml/snippet13.ml create mode 100644 src/content/1.7/code/ocaml/snippet14.ml create mode 100644 src/content/1.7/code/ocaml/snippet15.ml create mode 100644 src/content/1.7/code/ocaml/snippet16.ml create mode 100644 src/content/1.7/code/ocaml/snippet17.ml create mode 100644 src/content/1.7/code/ocaml/snippet18.ml create mode 100644 src/content/1.7/code/ocaml/snippet19.ml create mode 100644 src/content/1.7/code/ocaml/snippet20.ml create mode 100644 src/content/1.7/code/ocaml/snippet21.ml create mode 100644 src/content/1.7/code/ocaml/snippet22.ml create mode 100644 src/content/1.7/code/ocaml/snippet23.ml create mode 100644 src/content/1.7/code/ocaml/snippet24.ml create mode 100644 src/content/1.7/code/ocaml/snippet25.ml create mode 100644 src/content/1.7/code/ocaml/snippet26.ml create mode 100644 src/content/1.7/code/ocaml/snippet27.ml create mode 100644 src/content/1.7/code/ocaml/snippet28.ml create mode 100644 src/content/1.7/code/ocaml/snippet29.ml create mode 100644 src/content/1.7/code/ocaml/snippet30.ml create mode 100644 src/content/1.7/code/ocaml/snippet31.ml create mode 100644 src/content/1.7/code/ocaml/snippet32.ml create mode 100644 src/content/1.7/code/ocaml/snippet33.ml create mode 100644 src/content/1.7/code/ocaml/snippet34.ml create mode 100644 src/content/1.7/code/ocaml/snippet35.ml create mode 100644 src/content/1.8/code/ocaml/snippet01.ml create mode 100644 src/content/1.8/code/ocaml/snippet02.ml create mode 100644 src/content/1.8/code/ocaml/snippet03.ml create mode 100644 src/content/1.8/code/ocaml/snippet04.ml create mode 100644 src/content/1.8/code/ocaml/snippet05.ml create mode 100644 src/content/1.8/code/ocaml/snippet06.ml create mode 100644 src/content/1.8/code/ocaml/snippet07.ml create mode 100644 src/content/1.8/code/ocaml/snippet08.ml create mode 100644 src/content/1.8/code/ocaml/snippet09.ml create mode 100644 src/content/1.8/code/ocaml/snippet10.ml create mode 100644 src/content/1.8/code/ocaml/snippet11.ml create mode 100644 src/content/1.8/code/ocaml/snippet12.ml create mode 100644 src/content/1.8/code/ocaml/snippet13.ml create mode 100644 src/content/1.8/code/ocaml/snippet14.ml create mode 100644 src/content/1.8/code/ocaml/snippet15.ml create mode 100644 src/content/1.8/code/ocaml/snippet16.ml create mode 100644 src/content/1.8/code/ocaml/snippet17.ml create mode 100644 src/content/1.8/code/ocaml/snippet18.ml create mode 100644 src/content/1.8/code/ocaml/snippet19.ml create mode 100644 src/content/1.8/code/ocaml/snippet20.ml create mode 100644 src/content/1.8/code/ocaml/snippet21.ml create mode 100644 src/content/1.8/code/ocaml/snippet22.ml create mode 100644 src/content/1.8/code/ocaml/snippet23.ml create mode 100644 src/content/1.8/code/ocaml/snippet24.ml create mode 100644 src/content/1.8/code/ocaml/snippet25.ml create mode 100644 src/content/1.8/code/ocaml/snippet26.ml create mode 100644 src/content/1.8/code/ocaml/snippet27.ml create mode 100644 src/content/1.8/code/ocaml/snippet28.ml create mode 100644 src/content/1.8/code/ocaml/snippet29.ml create mode 100644 src/content/1.8/code/ocaml/snippet30.ml create mode 100644 src/content/1.9/code/ocaml/snippet01.ml create mode 100644 src/content/1.9/code/ocaml/snippet02.ml create mode 100644 src/content/1.9/code/ocaml/snippet03.ml create mode 100644 src/content/1.9/code/ocaml/snippet04.ml create mode 100644 src/content/1.9/code/ocaml/snippet05.ml create mode 100644 src/content/1.9/code/ocaml/snippet06.ml create mode 100644 src/content/1.9/code/ocaml/snippet07.ml create mode 100644 src/content/1.9/code/ocaml/snippet08.ml create mode 100644 src/content/1.9/code/ocaml/snippet09.ml create mode 100644 src/content/1.9/code/ocaml/snippet10.ml create mode 100644 src/content/1.9/code/ocaml/snippet11.ml create mode 100644 src/content/1.9/code/ocaml/snippet12.ml create mode 100644 src/content/1.9/code/ocaml/snippet13.ml create mode 100644 src/content/1.9/code/ocaml/snippet14.ml create mode 100644 src/content/1.9/code/ocaml/snippet15.ml create mode 100644 src/content/2.1/code/ocaml/snippet01.ml create mode 100644 src/content/2.1/code/ocaml/snippet02.ml create mode 100644 src/content/2.2/code/ocaml/snippet01.ml create mode 100644 src/content/2.2/code/ocaml/snippet02.ml create mode 100644 src/content/2.2/code/ocaml/snippet03.ml create mode 100644 src/content/2.2/code/ocaml/snippet04.ml create mode 100644 src/content/2.2/code/ocaml/snippet05.ml create mode 100644 src/content/2.2/code/ocaml/snippet06.ml create mode 100644 src/content/2.2/code/ocaml/snippet07.ml create mode 100644 src/content/2.2/code/ocaml/snippet08.ml create mode 100644 src/content/2.2/code/ocaml/snippet09.ml create mode 100644 src/content/2.2/code/ocaml/snippet10.ml create mode 100644 src/content/2.2/code/ocaml/snippet11.ml create mode 100644 src/content/2.2/code/ocaml/snippet12.ml create mode 100644 src/content/2.2/code/ocaml/snippet13.ml create mode 100644 src/content/2.2/code/ocaml/snippet14.ml create mode 100644 src/content/2.2/code/ocaml/snippet15.ml create mode 100644 src/content/2.2/code/ocaml/snippet16.ml create mode 100644 src/content/2.2/code/ocaml/snippet17.ml create mode 100644 src/content/2.2/code/ocaml/snippet18.ml create mode 100644 src/content/2.2/code/ocaml/snippet19.ml create mode 100644 src/content/2.3/code/ocaml/snippet01.ml create mode 100644 src/content/2.3/code/ocaml/snippet02.ml create mode 100644 src/content/2.3/code/ocaml/snippet03.ml create mode 100644 src/content/2.3/code/ocaml/snippet04.ml create mode 100644 src/content/2.3/code/ocaml/snippet05.ml create mode 100644 src/content/2.3/code/ocaml/snippet06.ml create mode 100644 src/content/2.3/code/ocaml/snippet07.ml create mode 100644 src/content/2.3/code/ocaml/snippet08.ml create mode 100644 src/content/2.3/code/ocaml/snippet09.ml create mode 100644 src/content/2.3/code/ocaml/snippet10.ml create mode 100644 src/content/2.4/code/ocaml/snippet01.ml create mode 100644 src/content/2.4/code/ocaml/snippet02.ml create mode 100644 src/content/2.4/code/ocaml/snippet03.ml create mode 100644 src/content/2.4/code/ocaml/snippet04.ml create mode 100644 src/content/2.4/code/ocaml/snippet05.ml create mode 100644 src/content/2.4/code/ocaml/snippet06.ml create mode 100644 src/content/2.4/code/ocaml/snippet07.ml create mode 100644 src/content/2.4/code/ocaml/snippet08.ml create mode 100644 src/content/2.4/code/ocaml/snippet09.ml create mode 100644 src/content/2.4/code/ocaml/snippet10.ml create mode 100644 src/content/2.4/code/ocaml/snippet11.ml create mode 100644 src/content/2.4/code/ocaml/snippet12.ml create mode 100644 src/content/2.4/code/ocaml/snippet13.ml create mode 100644 src/content/2.4/code/ocaml/snippet14.ml create mode 100644 src/content/2.4/code/ocaml/snippet15.ml create mode 100644 src/content/2.5/code/ocaml/snippet01.ml create mode 100644 src/content/2.5/code/ocaml/snippet02.ml create mode 100644 src/content/2.5/code/ocaml/snippet03.ml create mode 100644 src/content/2.5/code/ocaml/snippet04.ml create mode 100644 src/content/2.5/code/ocaml/snippet05.ml create mode 100644 src/content/2.5/code/ocaml/snippet06.ml create mode 100644 src/content/2.5/code/ocaml/snippet07.ml create mode 100644 src/content/2.6/code/ocaml/snippet01.ml create mode 100644 src/content/2.6/code/ocaml/snippet02.ml create mode 100644 src/content/3.10/code/ocaml/snippet01.ml create mode 100644 src/content/3.10/code/ocaml/snippet02.ml create mode 100644 src/content/3.10/code/ocaml/snippet03.ml create mode 100644 src/content/3.10/code/ocaml/snippet04.ml create mode 100644 src/content/3.10/code/ocaml/snippet05.ml create mode 100644 src/content/3.10/code/ocaml/snippet06.ml create mode 100644 src/content/3.10/code/ocaml/snippet07.ml create mode 100644 src/content/3.10/code/ocaml/snippet08.ml create mode 100644 src/content/3.10/code/ocaml/snippet09.ml create mode 100644 src/content/3.10/code/ocaml/snippet10.ml create mode 100644 src/content/3.10/code/ocaml/snippet11.ml create mode 100644 src/content/3.10/code/ocaml/snippet12.ml create mode 100644 src/content/3.10/code/ocaml/snippet13.ml create mode 100644 src/content/3.10/code/ocaml/snippet14.ml create mode 100644 src/content/3.10/code/ocaml/snippet15.ml create mode 100644 src/content/3.10/code/ocaml/snippet16.ml create mode 100644 src/content/3.10/code/ocaml/snippet17.ml create mode 100644 src/content/3.10/code/ocaml/snippet18.ml create mode 100644 src/content/3.11/code/ocaml/snippet01.ml create mode 100644 src/content/3.11/code/ocaml/snippet02.ml create mode 100644 src/content/3.11/code/ocaml/snippet03.ml create mode 100644 src/content/3.11/code/ocaml/snippet04.ml create mode 100644 src/content/3.11/code/ocaml/snippet05.ml create mode 100644 src/content/3.11/code/ocaml/snippet06.ml create mode 100644 src/content/3.11/code/ocaml/snippet07.ml create mode 100644 src/content/3.11/code/ocaml/snippet08.ml create mode 100644 src/content/3.11/code/ocaml/snippet09.ml create mode 100644 src/content/3.11/code/ocaml/snippet10.ml create mode 100644 src/content/3.11/code/ocaml/snippet11.ml create mode 100644 src/content/3.11/code/ocaml/snippet12.ml create mode 100644 src/content/3.14/code/ocaml/snippet01.ml create mode 100644 src/content/3.14/code/ocaml/snippet02.ml create mode 100644 src/content/3.14/code/ocaml/snippet03.ml create mode 100644 src/content/3.14/code/ocaml/snippet04.ml create mode 100644 src/content/3.2/code/ocaml/snippet01.ml create mode 100644 src/content/3.2/code/ocaml/snippet02.ml create mode 100644 src/content/3.2/code/ocaml/snippet03.ml create mode 100644 src/content/3.2/code/ocaml/snippet04.ml create mode 100644 src/content/3.2/code/ocaml/snippet05.ml create mode 100644 src/content/3.2/code/ocaml/snippet06.ml create mode 100644 src/content/3.2/code/ocaml/snippet07.ml create mode 100644 src/content/3.2/code/ocaml/snippet08.ml create mode 100644 src/content/3.2/code/ocaml/snippet09.ml create mode 100644 src/content/3.3/code/ocaml/snippet01.ml create mode 100644 src/content/3.3/code/ocaml/snippet02.ml create mode 100644 src/content/3.4/code/ocaml/snippet01.ml create mode 100644 src/content/3.4/code/ocaml/snippet02.ml create mode 100644 src/content/3.4/code/ocaml/snippet03.ml create mode 100644 src/content/3.4/code/ocaml/snippet04.ml create mode 100644 src/content/3.4/code/ocaml/snippet05.ml create mode 100644 src/content/3.4/code/ocaml/snippet06.ml create mode 100644 src/content/3.4/code/ocaml/snippet07.ml create mode 100644 src/content/3.4/code/ocaml/snippet08.ml create mode 100644 src/content/3.4/code/ocaml/snippet09.ml create mode 100644 src/content/3.4/code/ocaml/snippet10.ml create mode 100644 src/content/3.4/code/ocaml/snippet11.ml create mode 100644 src/content/3.4/code/ocaml/snippet12.ml create mode 100644 src/content/3.4/code/ocaml/snippet13.ml create mode 100644 src/content/3.4/code/ocaml/snippet14.ml create mode 100644 src/content/3.4/code/ocaml/snippet15.ml create mode 100644 src/content/3.4/code/ocaml/snippet16.ml create mode 100644 src/content/3.4/code/ocaml/snippet17.ml create mode 100644 src/content/3.4/code/ocaml/snippet18.ml create mode 100644 src/content/3.4/code/ocaml/snippet19.ml create mode 100644 src/content/3.4/code/ocaml/snippet20.ml create mode 100644 src/content/3.4/code/ocaml/snippet21.ml create mode 100644 src/content/3.4/code/ocaml/snippet22.ml create mode 100644 src/content/3.4/code/ocaml/snippet23.ml create mode 100644 src/content/3.4/code/ocaml/snippet24.ml create mode 100644 src/content/3.4/code/ocaml/snippet25.ml create mode 100644 src/content/3.5/code/ocaml/snippet01.ml create mode 100644 src/content/3.5/code/ocaml/snippet02.ml create mode 100644 src/content/3.5/code/ocaml/snippet03.ml create mode 100644 src/content/3.5/code/ocaml/snippet04.ml create mode 100644 src/content/3.5/code/ocaml/snippet05.ml create mode 100644 src/content/3.5/code/ocaml/snippet06.ml create mode 100644 src/content/3.5/code/ocaml/snippet07.ml create mode 100644 src/content/3.5/code/ocaml/snippet08.ml create mode 100644 src/content/3.5/code/ocaml/snippet09.ml create mode 100644 src/content/3.5/code/ocaml/snippet10.ml create mode 100644 src/content/3.5/code/ocaml/snippet11.ml create mode 100644 src/content/3.5/code/ocaml/snippet12.ml create mode 100644 src/content/3.5/code/ocaml/snippet13.ml create mode 100644 src/content/3.5/code/ocaml/snippet14.ml create mode 100644 src/content/3.5/code/ocaml/snippet15.ml create mode 100644 src/content/3.5/code/ocaml/snippet16.ml create mode 100644 src/content/3.5/code/ocaml/snippet17.ml create mode 100644 src/content/3.5/code/ocaml/snippet18.ml create mode 100644 src/content/3.5/code/ocaml/snippet19.ml create mode 100644 src/content/3.5/code/ocaml/snippet20.ml create mode 100644 src/content/3.5/code/ocaml/snippet21.ml create mode 100644 src/content/3.5/code/ocaml/snippet22.ml create mode 100644 src/content/3.5/code/ocaml/snippet23.ml create mode 100644 src/content/3.5/code/ocaml/snippet24.ml create mode 100644 src/content/3.5/code/ocaml/snippet25.ml create mode 100644 src/content/3.5/code/ocaml/snippet26.ml create mode 100644 src/content/3.5/code/ocaml/snippet27.ml create mode 100644 src/content/3.5/code/ocaml/snippet28.ml create mode 100644 src/content/3.5/code/ocaml/snippet29.ml create mode 100644 src/content/3.5/code/ocaml/snippet30.ml create mode 100644 src/content/3.5/code/ocaml/snippet31.ml create mode 100644 src/content/3.5/code/ocaml/snippet32.ml create mode 100644 src/content/3.5/code/ocaml/snippet33.ml create mode 100644 src/content/3.5/code/ocaml/snippet34.ml create mode 100644 src/content/3.5/code/ocaml/snippet35.ml create mode 100644 src/content/3.5/code/ocaml/snippet36.ml create mode 100644 src/content/3.5/code/ocaml/snippet37.ml create mode 100644 src/content/3.6/code/ocaml/snippet01.ml create mode 100644 src/content/3.6/code/ocaml/snippet02.ml create mode 100644 src/content/3.6/code/ocaml/snippet03.ml create mode 100644 src/content/3.6/code/ocaml/snippet04.ml create mode 100644 src/content/3.6/code/ocaml/snippet05.ml create mode 100644 src/content/3.6/code/ocaml/snippet06.ml create mode 100644 src/content/3.6/code/ocaml/snippet07.ml create mode 100644 src/content/3.6/code/ocaml/snippet08.ml create mode 100644 src/content/3.6/code/ocaml/snippet09.ml create mode 100644 src/content/3.6/code/ocaml/snippet10.ml create mode 100644 src/content/3.6/code/ocaml/snippet11.ml create mode 100644 src/content/3.6/code/ocaml/snippet12.ml create mode 100644 src/content/3.6/code/ocaml/snippet13.ml create mode 100644 src/content/3.6/code/ocaml/snippet14.ml create mode 100644 src/content/3.6/code/ocaml/snippet15.ml create mode 100644 src/content/3.6/code/ocaml/snippet16.ml create mode 100644 src/content/3.6/code/ocaml/snippet17.ml create mode 100644 src/content/3.6/code/ocaml/snippet18.ml create mode 100644 src/content/3.6/code/ocaml/snippet19.ml create mode 100644 src/content/3.6/code/ocaml/snippet20.ml create mode 100644 src/content/3.6/code/ocaml/snippet21.ml create mode 100644 src/content/3.6/code/ocaml/snippet22.ml create mode 100644 src/content/3.6/code/ocaml/snippet23.ml create mode 100644 src/content/3.6/code/ocaml/snippet24.ml create mode 100644 src/content/3.6/code/ocaml/snippet25.ml create mode 100644 src/content/3.7/code/ocaml/snippet01.ml create mode 100644 src/content/3.7/code/ocaml/snippet02.ml create mode 100644 src/content/3.7/code/ocaml/snippet03.ml create mode 100644 src/content/3.7/code/ocaml/snippet04.ml create mode 100644 src/content/3.7/code/ocaml/snippet05.ml create mode 100644 src/content/3.7/code/ocaml/snippet06.ml create mode 100644 src/content/3.7/code/ocaml/snippet07.ml create mode 100644 src/content/3.7/code/ocaml/snippet08.ml create mode 100644 src/content/3.7/code/ocaml/snippet09.ml create mode 100644 src/content/3.7/code/ocaml/snippet10.ml create mode 100644 src/content/3.7/code/ocaml/snippet11.ml create mode 100644 src/content/3.7/code/ocaml/snippet12.ml create mode 100644 src/content/3.7/code/ocaml/snippet13.ml create mode 100644 src/content/3.7/code/ocaml/snippet14.ml create mode 100644 src/content/3.7/code/ocaml/snippet15.ml create mode 100644 src/content/3.7/code/ocaml/snippet16.ml create mode 100644 src/content/3.7/code/ocaml/snippet17.ml create mode 100644 src/content/3.7/code/ocaml/snippet18.ml create mode 100644 src/content/3.7/code/ocaml/snippet19.ml create mode 100644 src/content/3.7/code/ocaml/snippet20.ml create mode 100644 src/content/3.7/code/ocaml/snippet21.ml create mode 100644 src/content/3.7/code/ocaml/snippet22.ml create mode 100644 src/content/3.7/code/ocaml/snippet23.ml create mode 100644 src/content/3.7/code/ocaml/snippet24.ml create mode 100644 src/content/3.7/code/ocaml/snippet25.ml create mode 100644 src/content/3.7/code/ocaml/snippet26.ml create mode 100644 src/content/3.7/code/ocaml/snippet27.ml create mode 100644 src/content/3.7/code/ocaml/snippet28.ml create mode 100644 src/content/3.7/code/ocaml/snippet29.ml create mode 100644 src/content/3.7/code/ocaml/snippet30.ml create mode 100644 src/content/3.7/code/ocaml/snippet31.ml create mode 100644 src/content/3.7/code/ocaml/snippet32.ml create mode 100644 src/content/3.7/code/ocaml/snippet33.ml create mode 100644 src/content/3.7/code/ocaml/snippet34.ml create mode 100644 src/content/3.7/code/ocaml/snippet35.ml create mode 100644 src/content/3.7/code/ocaml/snippet36.ml create mode 100644 src/content/3.7/code/ocaml/snippet37.ml create mode 100644 src/content/3.7/code/ocaml/snippet38.ml create mode 100644 src/content/3.7/code/ocaml/snippet39.ml create mode 100644 src/content/3.8/code/ocaml/snippet01.ml create mode 100644 src/content/3.8/code/ocaml/snippet02.ml create mode 100644 src/content/3.8/code/ocaml/snippet03.ml create mode 100644 src/content/3.8/code/ocaml/snippet04.ml create mode 100644 src/content/3.8/code/ocaml/snippet05.ml create mode 100644 src/content/3.8/code/ocaml/snippet06.ml create mode 100644 src/content/3.8/code/ocaml/snippet07.ml create mode 100644 src/content/3.8/code/ocaml/snippet08.ml create mode 100644 src/content/3.8/code/ocaml/snippet09.ml create mode 100644 src/content/3.8/code/ocaml/snippet10.ml create mode 100644 src/content/3.8/code/ocaml/snippet11.ml create mode 100644 src/content/3.8/code/ocaml/snippet12.ml create mode 100644 src/content/3.8/code/ocaml/snippet13.ml create mode 100644 src/content/3.8/code/ocaml/snippet14.ml create mode 100644 src/content/3.8/code/ocaml/snippet15.ml create mode 100644 src/content/3.8/code/ocaml/snippet16.ml create mode 100644 src/content/3.8/code/ocaml/snippet17.ml create mode 100644 src/content/3.8/code/ocaml/snippet18.ml create mode 100644 src/content/3.8/code/ocaml/snippet19.ml create mode 100644 src/content/3.8/code/ocaml/snippet20.ml create mode 100644 src/content/3.8/code/ocaml/snippet21.ml create mode 100644 src/content/3.8/code/ocaml/snippet22.ml create mode 100644 src/content/3.8/code/ocaml/snippet23.ml create mode 100644 src/content/3.8/code/ocaml/snippet24.ml create mode 100644 src/content/3.8/code/ocaml/snippet25.ml create mode 100644 src/content/3.8/code/ocaml/snippet26.ml create mode 100644 src/content/3.8/code/ocaml/snippet27.ml create mode 100644 src/content/3.8/code/ocaml/snippet28.ml create mode 100644 src/content/3.8/code/ocaml/snippet29.ml create mode 100644 src/content/3.8/code/ocaml/snippet30.ml create mode 100644 src/content/3.8/code/ocaml/snippet31.ml create mode 100644 src/content/3.8/code/ocaml/snippet32.ml create mode 100644 src/content/3.8/code/ocaml/snippet33.ml create mode 100644 src/content/3.8/code/ocaml/snippet34.ml create mode 100644 src/content/3.8/code/ocaml/snippet35.ml create mode 100644 src/content/3.9/code/ocaml/snippet01.ml create mode 100644 src/content/3.9/code/ocaml/snippet02.ml create mode 100644 src/content/3.9/code/ocaml/snippet03.ml create mode 100644 src/content/3.9/code/ocaml/snippet04.ml create mode 100644 src/content/3.9/code/ocaml/snippet05.ml create mode 100644 src/content/3.9/code/ocaml/snippet06.ml create mode 100644 src/content/3.9/code/ocaml/snippet07.ml create mode 100644 src/content/3.9/code/ocaml/snippet08.ml create mode 100644 src/content/3.9/code/ocaml/snippet09.ml create mode 100644 src/content/3.9/code/ocaml/snippet10.ml create mode 100644 src/content/3.9/code/ocaml/snippet11.ml create mode 100644 src/content/3.9/code/ocaml/snippet12.ml create mode 100644 src/content/3.9/code/ocaml/snippet13.ml create mode 100644 src/content/3.9/code/ocaml/snippet14.ml create mode 100644 src/content/3.9/code/ocaml/snippet15.ml create mode 100644 src/content/ocaml/colophon.tex create mode 100644 src/content/ocaml/editor-note.tex create mode 100644 src/ctfp-print-ocaml.tex create mode 100644 src/ctfp-reader-ocaml.tex create mode 100644 src/fig/icons/ocaml.png create mode 100644 src/opt-ocaml.tex diff --git a/src/Makefile b/src/Makefile index 5d5823b3..f05f7e9e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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 +.PHONY: default all clean out-dir version.tex scala ocaml DIR := $(shell pwd) GIT_VER := $(shell git describe --tags --always --long | tr -d '\n') @@ -13,8 +13,10 @@ DEFAULTTOPTEX = ctfp-reader.tex ctfp-print.tex SCALATEXFILES = ctfp-reader-scala.tex ctfp-print-scala.tex # todo make this a macro +OCAMLTEXFILES = ctfp-reader-ocaml.tex ctfp-print-ocaml.tex # todo make this a macro + # Top-level LaTeX files from which CTFP book can be generated -TOPTEXFILES = version.tex $(DEFAULTTOPTEX) $(SCALATEXFILES) +TOPTEXFILES = version.tex $(DEFAULTTOPTEX) $(SCALATEXFILES) $(OCAMLTEXFILES) # Default PDF file to make DEFAULTPDF:=$(DEFAULTTOPTEX:.tex=.pdf) @@ -22,7 +24,10 @@ DEFAULTPDF:=$(DEFAULTTOPTEX:.tex=.pdf) # Scala PDF file to make SCALAPDF:=$(SCALATEXFILES:.tex=.pdf) -# Other PDF files for the CTFP book +# OCaml PDF file to make +OCAMLPDF:=$(OCAMLTEXFILES:.tex=.pdf) + +# Other PDF files for the CTFP book TOPPDFFILES:=$(TOPTEXFILES:.tex=.pdf) # Configuration files @@ -31,7 +36,7 @@ OPTFILES = opt-print-ustrade.tex \ opt-scala.tex # All the LaTeX files for the CTFP book in order of dependency -TEXFILES = $(TOPTEXFILES) $(SCALATEXFILES) $(OPTFILES) +TEXFILES = $(TOPTEXFILES) $(SCALATEXFILES) $(OCAMLTEXFILES) $(OPTFILES) default: suffix='' default: out-dir $(DEFAULTPDF) # todo cover @@ -41,6 +46,9 @@ all: default scala scala: suffix='-scala' scala: out-dir version.tex $(SCALAPDF) +ocaml: suffix='-ocaml' +ocaml: out-dir version.tex $(OCAMLPDF) + # Main targets $(TOPPDFFILES) : %.pdf : %.tex $(TEXFILES) if which latexmk > /dev/null 2>&1 ;\ @@ -64,5 +72,5 @@ clean: if which latexmk > /dev/null 2>&1 ; then latexmk -CA; fi rm -rf ../out -clean-minted: +clean-minted: rm -rf _minted-* diff --git a/src/content/1.1/code/ocaml/snippet01.ml b/src/content/1.1/code/ocaml/snippet01.ml new file mode 100644 index 00000000..4343c96c --- /dev/null +++ b/src/content/1.1/code/ocaml/snippet01.ml @@ -0,0 +1,6 @@ +module type Polymorphic_Function_F = sig + type a + type b + + val f : a -> b +end diff --git a/src/content/1.1/code/ocaml/snippet02.ml b/src/content/1.1/code/ocaml/snippet02.ml new file mode 100644 index 00000000..33b36136 --- /dev/null +++ b/src/content/1.1/code/ocaml/snippet02.ml @@ -0,0 +1,6 @@ +module type Polymorphic_Function_G = sig + type b + type c + + val g : b -> c +end diff --git a/src/content/1.1/code/ocaml/snippet03.ml b/src/content/1.1/code/ocaml/snippet03.ml new file mode 100644 index 00000000..9ec1d227 --- /dev/null +++ b/src/content/1.1/code/ocaml/snippet03.ml @@ -0,0 +1,9 @@ +module Compose_Example + (F : Polymorphic_Function_F) + (G : Polymorphic_Function_G with type b = F.b) = +struct + (** OCaml doesn't have a compose operator. So, creating one. **) + let ( >> ) g f x = g (f x) + + let compose : 'a -> 'c = G.g >> F.f +end diff --git a/src/content/1.1/code/ocaml/snippet04.ml b/src/content/1.1/code/ocaml/snippet04.ml new file mode 100644 index 00000000..a74aa394 --- /dev/null +++ b/src/content/1.1/code/ocaml/snippet04.ml @@ -0,0 +1,9 @@ +module Compose_Three_GF = functor(F:Polymorphic_Function_F)(G:Polymorphic_Function_G with type b = F.b)(H:Polymorphic_Function_H with type c = G.c) -> struct + let compose : 'a -> 'd = H.h >> (G.g >> F.f) +end + +module Compose_Three_HG = functor(F:Polymorphic_Function_F)(G:Polymorphic_Function_G with type b = F.b)(H:Polymorphic_Function_H with type c = G.c) -> struct + let compose : 'a -> 'd = (H.h >> G.g) >> F.f +end + +Compose_Three_GF.compose = Compose_Three_HG.compose diff --git a/src/content/1.1/code/ocaml/snippet05.ml b/src/content/1.1/code/ocaml/snippet05.ml new file mode 100644 index 00000000..f54d47a8 --- /dev/null +++ b/src/content/1.1/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +let id x = x diff --git a/src/content/1.1/code/ocaml/snippet06.ml b/src/content/1.1/code/ocaml/snippet06.ml new file mode 100644 index 00000000..33456482 --- /dev/null +++ b/src/content/1.1/code/ocaml/snippet06.ml @@ -0,0 +1,2 @@ +f >> id +id >> f diff --git a/src/content/1.10/code/ocaml/snippet01.ml b/src/content/1.10/code/ocaml/snippet01.ml new file mode 100644 index 00000000..49d53349 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +val alpha : 'a . 'a f -> 'a g diff --git a/src/content/1.10/code/ocaml/snippet02.ml b/src/content/1.10/code/ocaml/snippet02.ml new file mode 100644 index 00000000..cf63465a --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +val alpha : 'a f -> 'a g diff --git a/src/content/1.10/code/ocaml/snippet03.ml b/src/content/1.10/code/ocaml/snippet03.ml new file mode 100644 index 00000000..cf63465a --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet03.ml @@ -0,0 +1 @@ +val alpha : 'a f -> 'a g diff --git a/src/content/1.10/code/ocaml/snippet04.ml b/src/content/1.10/code/ocaml/snippet04.ml new file mode 100644 index 00000000..69990e13 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet04.ml @@ -0,0 +1,4 @@ +let safe_head = function + | [] -> None + | x :: xs -> Some x +;; diff --git a/src/content/1.10/code/ocaml/snippet05.ml b/src/content/1.10/code/ocaml/snippet05.ml new file mode 100644 index 00000000..13f897cf --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +compose (fmap f) safe_head = compose safe_head (fmap f) diff --git a/src/content/1.10/code/ocaml/snippet06.ml b/src/content/1.10/code/ocaml/snippet06.ml new file mode 100644 index 00000000..e6882bae --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet06.ml @@ -0,0 +1,2 @@ +(* Starting with empty list *) +let fmap f (safe_head []) = fmap f None = None diff --git a/src/content/1.10/code/ocaml/snippet07.ml b/src/content/1.10/code/ocaml/snippet07.ml new file mode 100644 index 00000000..f4ac2511 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +let safe_head (fmap f []) = safe_head [] = None diff --git a/src/content/1.10/code/ocaml/snippet08.ml b/src/content/1.10/code/ocaml/snippet08.ml new file mode 100644 index 00000000..0c411cf2 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +let fmap f (safe_head (x :: xs)) = fmap f (Some x)= Some (f x) diff --git a/src/content/1.10/code/ocaml/snippet09.ml b/src/content/1.10/code/ocaml/snippet09.ml new file mode 100644 index 00000000..abe3681a --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet09.ml @@ -0,0 +1 @@ +let safe_head (fmap f (x :: xs)) = safe_head (f x :: f xs) = Some (f x) diff --git a/src/content/1.10/code/ocaml/snippet10.ml b/src/content/1.10/code/ocaml/snippet10.ml new file mode 100644 index 00000000..fa7be49a --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet10.ml @@ -0,0 +1,4 @@ +let rec fmap f = function + | [] -> [] + | x :: xs -> f x :: fmap f xs +;; diff --git a/src/content/1.10/code/ocaml/snippet11.ml b/src/content/1.10/code/ocaml/snippet11.ml new file mode 100644 index 00000000..9ee8d922 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet11.ml @@ -0,0 +1,4 @@ +let rec fmap f = function + | None -> None + | Some x -> Some (f x) +;; diff --git a/src/content/1.10/code/ocaml/snippet12.ml b/src/content/1.10/code/ocaml/snippet12.ml new file mode 100644 index 00000000..d8f69fc7 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet12.ml @@ -0,0 +1,8 @@ +(** OCaml requires mutually recursive functions to be defined together *) +let rec length : 'a list -> (int, 'a) const = function + | [] -> Const 0 + | _ :: xs -> Const (1 + un_const (length xs)) + +and un_const : 'c 'a. ('c, 'a) const -> 'c = function + | Const c -> c +;; diff --git a/src/content/1.10/code/ocaml/snippet13.ml b/src/content/1.10/code/ocaml/snippet13.ml new file mode 100644 index 00000000..e9414f51 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet13.ml @@ -0,0 +1,3 @@ +let un_const : 'c 'a. ('c, 'a) const -> 'c = function + | Const c -> c +;; diff --git a/src/content/1.10/code/ocaml/snippet14.ml b/src/content/1.10/code/ocaml/snippet14.ml new file mode 100644 index 00000000..33f6a6f1 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet14.ml @@ -0,0 +1 @@ +val length : 'a list -> int diff --git a/src/content/1.10/code/ocaml/snippet15.ml b/src/content/1.10/code/ocaml/snippet15.ml new file mode 100644 index 00000000..8e302b76 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet15.ml @@ -0,0 +1,3 @@ +let scam : 'a. ('int, 'a) const -> 'a option = function + | Const a -> None +;; diff --git a/src/content/1.10/code/ocaml/snippet16.ml b/src/content/1.10/code/ocaml/snippet16.ml new file mode 100644 index 00000000..1aa05bd8 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet16.ml @@ -0,0 +1 @@ +type ('e, 'a) reader = Reader of ('e -> 'a) diff --git a/src/content/1.10/code/ocaml/snippet17.ml b/src/content/1.10/code/ocaml/snippet17.ml new file mode 100644 index 00000000..aaedbf3a --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet17.ml @@ -0,0 +1,10 @@ +module Reader_Functor (T : sig + type e +end) : Functor = struct + type 'a t = (T.e, 'a) reader + + let fmap : 'a 'b. ('a -> 'b) -> 'a t -> 'b t = + fun f -> function + | Reader r -> Reader (compose f r) + ;; +end diff --git a/src/content/1.10/code/ocaml/snippet18.ml b/src/content/1.10/code/ocaml/snippet18.ml new file mode 100644 index 00000000..7d551206 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet18.ml @@ -0,0 +1 @@ +val alpha : (unit, 'a) reader -> 'a option diff --git a/src/content/1.10/code/ocaml/snippet19.ml b/src/content/1.10/code/ocaml/snippet19.ml new file mode 100644 index 00000000..84ac342f --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet19.ml @@ -0,0 +1,3 @@ +let dumb : 'a. (unit, 'a) reader -> 'a option = function + | Reader _ -> None +;; diff --git a/src/content/1.10/code/ocaml/snippet20.ml b/src/content/1.10/code/ocaml/snippet20.ml new file mode 100644 index 00000000..c015712b --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet20.ml @@ -0,0 +1,3 @@ +let obvious : 'a. (unit, 'a) reader -> 'a option = function + | Reader f -> Some (f ()) +;; diff --git a/src/content/1.10/code/ocaml/snippet21.ml b/src/content/1.10/code/ocaml/snippet21.ml new file mode 100644 index 00000000..5baf5900 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet21.ml @@ -0,0 +1 @@ +type ('r, 'a) op = Op of ('a -> 'r) diff --git a/src/content/1.10/code/ocaml/snippet22.ml b/src/content/1.10/code/ocaml/snippet22.ml new file mode 100644 index 00000000..ae670217 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet22.ml @@ -0,0 +1,10 @@ +module Op_Contravariant (T : sig + type r +end) : Contravariant = struct + type 'a t = (T.r, 'a) op + + let contramap : ('b -> 'a) -> 'a t -> 'b t = + fun f -> function + | Op g -> Op (compose g f) + ;; +end diff --git a/src/content/1.10/code/ocaml/snippet23.ml b/src/content/1.10/code/ocaml/snippet23.ml new file mode 100644 index 00000000..a93249ec --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet23.ml @@ -0,0 +1,3 @@ +let pred_to_str = function + | Op f -> Op (fun x -> if f x then "T" else "F") +;; diff --git a/src/content/1.10/code/ocaml/snippet24.ml b/src/content/1.10/code/ocaml/snippet24.ml new file mode 100644 index 00000000..f58a24f2 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet24.ml @@ -0,0 +1 @@ +compose (contramap f) pred_to_str = compose pred_to_str (contramap f) diff --git a/src/content/1.10/code/ocaml/snippet25.ml b/src/content/1.10/code/ocaml/snippet25.ml new file mode 100644 index 00000000..20e7bc07 --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet25.ml @@ -0,0 +1,7 @@ +module Op_Bool = Op_Contravariant (struct + type r = bool +end) + +let op_bool_contramap : ('b -> 'a) -> 'a Op_Bool.t -> 'b Op_Bool.t = + Op_Bool.contramap +;; diff --git a/src/content/1.10/code/ocaml/snippet26.ml b/src/content/1.10/code/ocaml/snippet26.ml new file mode 100644 index 00000000..1e17379d --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet26.ml @@ -0,0 +1 @@ +'a -> 'a diff --git a/src/content/1.10/code/ocaml/snippet27.ml b/src/content/1.10/code/ocaml/snippet27.ml new file mode 100644 index 00000000..bcd4326a --- /dev/null +++ b/src/content/1.10/code/ocaml/snippet27.ml @@ -0,0 +1 @@ +('a -> 'a) -> 'a f diff --git a/src/content/1.2/code/ocaml/snippet01.ml b/src/content/1.2/code/ocaml/snippet01.ml new file mode 100644 index 00000000..6aedf3e2 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet01.ml @@ -0,0 +1,3 @@ +module type Chapter2_DeclareVariable = sig + val x : int +end diff --git a/src/content/1.2/code/ocaml/snippet010.ml b/src/content/1.2/code/ocaml/snippet010.ml new file mode 100644 index 00000000..848f09b7 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet010.ml @@ -0,0 +1 @@ +let unit _ = () diff --git a/src/content/1.2/code/ocaml/snippet011.ml b/src/content/1.2/code/ocaml/snippet011.ml new file mode 100644 index 00000000..640d192e --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet011.ml @@ -0,0 +1,3 @@ +type bool = + | false + | true diff --git a/src/content/1.2/code/ocaml/snippet02.ml b/src/content/1.2/code/ocaml/snippet02.ml new file mode 100644 index 00000000..d463de59 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet02.ml @@ -0,0 +1,3 @@ +module type Chapter2_DeclareFunction = sig + val f : bool -> bool +end diff --git a/src/content/1.2/code/ocaml/snippet03.ml b/src/content/1.2/code/ocaml/snippet03.ml new file mode 100644 index 00000000..2a140d02 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet03.ml @@ -0,0 +1,3 @@ +module Chapter2_Bottom : Chapter2_DeclareFunction = struct + let f (b : bool) : bool = failwith "Not Implemented" +end diff --git a/src/content/1.2/code/ocaml/snippet04.ml b/src/content/1.2/code/ocaml/snippet04.ml new file mode 100644 index 00000000..36a1faf9 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet04.ml @@ -0,0 +1,3 @@ +module Chapter2_Bottom : Chapter2_DeclareFunction = struct + let f : bool -> bool = fun _ -> failwith "Not implemented" +end diff --git a/src/content/1.2/code/ocaml/snippet05.ml b/src/content/1.2/code/ocaml/snippet05.ml new file mode 100644 index 00000000..17852e43 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +let fact n = List.fold (List.range 1 n) ~init:1 ~f:( * ) diff --git a/src/content/1.2/code/ocaml/snippet06.ml b/src/content/1.2/code/ocaml/snippet06.ml new file mode 100644 index 00000000..49d3ba47 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet06.ml @@ -0,0 +1,3 @@ +type void + +let rec absurd (x : void) = absurd x diff --git a/src/content/1.2/code/ocaml/snippet07.ml b/src/content/1.2/code/ocaml/snippet07.ml new file mode 100644 index 00000000..225aa9b7 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +let f44 () : int = 44 diff --git a/src/content/1.2/code/ocaml/snippet08.ml b/src/content/1.2/code/ocaml/snippet08.ml new file mode 100644 index 00000000..b887dd9c --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +let f_int (x : int) = () diff --git a/src/content/1.2/code/ocaml/snippet09.ml b/src/content/1.2/code/ocaml/snippet09.ml new file mode 100644 index 00000000..f134290c --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet09.ml @@ -0,0 +1 @@ +let f_int (_ : int) = () diff --git a/src/content/1.2/code/ocaml/snippet10.ml b/src/content/1.2/code/ocaml/snippet10.ml new file mode 100644 index 00000000..848f09b7 --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet10.ml @@ -0,0 +1 @@ +let unit _ = () diff --git a/src/content/1.2/code/ocaml/snippet11.ml b/src/content/1.2/code/ocaml/snippet11.ml new file mode 100644 index 00000000..640d192e --- /dev/null +++ b/src/content/1.2/code/ocaml/snippet11.ml @@ -0,0 +1,3 @@ +type bool = + | false + | true diff --git a/src/content/1.3/code/ocaml/snippet01.ml b/src/content/1.3/code/ocaml/snippet01.ml new file mode 100644 index 00000000..4f8b6bd0 --- /dev/null +++ b/src/content/1.3/code/ocaml/snippet01.ml @@ -0,0 +1,6 @@ +module type Monoid = sig + type a + + val mempty : a + val mappend : a -> a -> a +end diff --git a/src/content/1.3/code/ocaml/snippet02.ml b/src/content/1.3/code/ocaml/snippet02.ml new file mode 100644 index 00000000..3fdc5834 --- /dev/null +++ b/src/content/1.3/code/ocaml/snippet02.ml @@ -0,0 +1,6 @@ +module StringMonoid : Monoid = struct + type a = string + + let mempty = "" + let mappend = ( ^ ) +end diff --git a/src/content/1.4/code/ocaml/snippet01.ml b/src/content/1.4/code/ocaml/snippet01.ml new file mode 100644 index 00000000..6474dfa7 --- /dev/null +++ b/src/content/1.4/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +type 'a writer = 'a * string diff --git a/src/content/1.4/code/ocaml/snippet02.ml b/src/content/1.4/code/ocaml/snippet02.ml new file mode 100644 index 00000000..fd5303d1 --- /dev/null +++ b/src/content/1.4/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +'a -> 'b writer diff --git a/src/content/1.4/code/ocaml/snippet03.ml b/src/content/1.4/code/ocaml/snippet03.ml new file mode 100644 index 00000000..b5533bd7 --- /dev/null +++ b/src/content/1.4/code/ocaml/snippet03.ml @@ -0,0 +1,7 @@ +module type Kleisli = sig + type a + type b + type c + + val ( >=> ) : (a -> b writer) -> (b -> c writer) -> a -> c writer +end diff --git a/src/content/1.4/code/ocaml/snippet04.ml b/src/content/1.4/code/ocaml/snippet04.ml new file mode 100644 index 00000000..d7c311f4 --- /dev/null +++ b/src/content/1.4/code/ocaml/snippet04.ml @@ -0,0 +1 @@ +let pure x = x, "" diff --git a/src/content/1.4/code/ocaml/snippet05.ml b/src/content/1.4/code/ocaml/snippet05.ml new file mode 100644 index 00000000..380e46a5 --- /dev/null +++ b/src/content/1.4/code/ocaml/snippet05.ml @@ -0,0 +1,3 @@ +let up_case : string -> string writer = + fun s -> String.uppercase s, "up_case " +;; diff --git a/src/content/1.4/code/ocaml/snippet06.ml b/src/content/1.4/code/ocaml/snippet06.ml new file mode 100644 index 00000000..ed0f0d29 --- /dev/null +++ b/src/content/1.4/code/ocaml/snippet06.ml @@ -0,0 +1,3 @@ +let to_words : string -> string list writer = + fun s -> String.split s ~on:' ', "to_words " +;; diff --git a/src/content/1.4/code/ocaml/snippet07.ml b/src/content/1.4/code/ocaml/snippet07.ml new file mode 100644 index 00000000..67a030ea --- /dev/null +++ b/src/content/1.4/code/ocaml/snippet07.ml @@ -0,0 +1,10 @@ +module KleisiExample + (K : Kleisli + with type a = string + and type b = string + and type c = string list) = +struct + let up_case_and_to_words : string -> string list writer = + K.( >=> ) up_case to_words + ;; +end diff --git a/src/content/1.5/code/ocaml/snippet01.ml b/src/content/1.5/code/ocaml/snippet01.ml new file mode 100644 index 00000000..ffe51218 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet01.ml @@ -0,0 +1,3 @@ +type void (* Uninhabited type *) + +val absurd : void -> 'a diff --git a/src/content/1.5/code/ocaml/snippet02.ml b/src/content/1.5/code/ocaml/snippet02.ml new file mode 100644 index 00000000..638d9cec --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +let unit x = () diff --git a/src/content/1.5/code/ocaml/snippet03.ml b/src/content/1.5/code/ocaml/snippet03.ml new file mode 100644 index 00000000..6090112b --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet03.ml @@ -0,0 +1 @@ +let yes _ = true diff --git a/src/content/1.5/code/ocaml/snippet04.ml b/src/content/1.5/code/ocaml/snippet04.ml new file mode 100644 index 00000000..92da4811 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet04.ml @@ -0,0 +1 @@ +let no _ = false diff --git a/src/content/1.5/code/ocaml/snippet05.ml b/src/content/1.5/code/ocaml/snippet05.ml new file mode 100644 index 00000000..333a2030 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet05.ml @@ -0,0 +1,2 @@ +compose f g = id +compose g f = id diff --git a/src/content/1.5/code/ocaml/snippet06.ml b/src/content/1.5/code/ocaml/snippet06.ml new file mode 100644 index 00000000..b0a8bfad --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +let fst (a, b) = a diff --git a/src/content/1.5/code/ocaml/snippet07.ml b/src/content/1.5/code/ocaml/snippet07.ml new file mode 100644 index 00000000..5eb4f698 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +let snd (a, b) = b diff --git a/src/content/1.5/code/ocaml/snippet08.ml b/src/content/1.5/code/ocaml/snippet08.ml new file mode 100644 index 00000000..00c9de3f --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet08.ml @@ -0,0 +1,2 @@ +let fst (a, _) = a +let snd (_, b) = b diff --git a/src/content/1.5/code/ocaml/snippet09.ml b/src/content/1.5/code/ocaml/snippet09.ml new file mode 100644 index 00000000..208f275c --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet09.ml @@ -0,0 +1,8 @@ +module type Chapter5_Product = sig + type a + type c + type b + + val p : c -> a + val q : c -> b +end diff --git a/src/content/1.5/code/ocaml/snippet10.ml b/src/content/1.5/code/ocaml/snippet10.ml new file mode 100644 index 00000000..d6bcc864 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet10.ml @@ -0,0 +1,12 @@ +module Chapter5_Product_Example : + Chapter5_Product + with type a = int + and type b = bool + and type c = int = struct + type a = int + type b = bool + type c = int + + let p x = x + let q _ = true +end diff --git a/src/content/1.5/code/ocaml/snippet11.ml b/src/content/1.5/code/ocaml/snippet11.ml new file mode 100644 index 00000000..e26871c5 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet11.ml @@ -0,0 +1,8 @@ +module Chapter5_Product_Example2 : Chapter5_Product = struct + type a = int + type b = bool + type c = int * int * bool + + let p (x, _, _) = x + let q (_, _, b) = b +end diff --git a/src/content/1.5/code/ocaml/snippet12.ml b/src/content/1.5/code/ocaml/snippet12.ml new file mode 100644 index 00000000..e6f2e5ac --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet12.ml @@ -0,0 +1,2 @@ +let p' = compose Chapter5_Product_Example.p m +let q' = compose Chapter5_Product_Example.q m diff --git a/src/content/1.5/code/ocaml/snippet13.ml b/src/content/1.5/code/ocaml/snippet13.ml new file mode 100644 index 00000000..0f96438f --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet13.ml @@ -0,0 +1 @@ +let m (x : int) = x, true diff --git a/src/content/1.5/code/ocaml/snippet14.ml b/src/content/1.5/code/ocaml/snippet14.ml new file mode 100644 index 00000000..0d8b34ff --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet14.ml @@ -0,0 +1,2 @@ +let p x = fst (m x) +let q x = snd (m x) diff --git a/src/content/1.5/code/ocaml/snippet15.ml b/src/content/1.5/code/ocaml/snippet15.ml new file mode 100644 index 00000000..a872cc05 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet15.ml @@ -0,0 +1 @@ +let m ((x, _, b) : int * int * bool) = x, b diff --git a/src/content/1.5/code/ocaml/snippet16.ml b/src/content/1.5/code/ocaml/snippet16.ml new file mode 100644 index 00000000..f2729c26 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet16.ml @@ -0,0 +1,2 @@ +fst = compose p m' +snd = compose q m' diff --git a/src/content/1.5/code/ocaml/snippet17.ml b/src/content/1.5/code/ocaml/snippet17.ml new file mode 100644 index 00000000..a2edd3ed --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet17.ml @@ -0,0 +1 @@ +let m' ((x, b) : int * bool) = x, x, b diff --git a/src/content/1.5/code/ocaml/snippet18.ml b/src/content/1.5/code/ocaml/snippet18.ml new file mode 100644 index 00000000..54d91c93 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet18.ml @@ -0,0 +1 @@ +let m' ((x, b) : int * bool) = x, 42, b diff --git a/src/content/1.5/code/ocaml/snippet19.ml b/src/content/1.5/code/ocaml/snippet19.ml new file mode 100644 index 00000000..fbc911d9 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet19.ml @@ -0,0 +1,9 @@ +module type Chapter5_product_projection_example = functor + (Product : Chapter5_Product) + -> sig + val m : Product.c -> Product.a * Product.b +end + +module ProjectionImpl (Product : Chapter5_Product) = struct + let m c = Product.p c, Product.q c +end diff --git a/src/content/1.5/code/ocaml/snippet20.ml b/src/content/1.5/code/ocaml/snippet20.ml new file mode 100644 index 00000000..e998bb47 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet20.ml @@ -0,0 +1,11 @@ +module type Factorizer = functor (Product : Chapter5_Product) -> sig + val factorizer + : (Product.c -> Product.a) + -> (Product.c -> Product.b) + -> Product.c + -> Product.a * Product.b +end + +module FactorizerImpl (Product : Chapter5_Product) = struct + let factorizer ca cb = Product.p ca, Product.q cb +end diff --git a/src/content/1.5/code/ocaml/snippet21.ml b/src/content/1.5/code/ocaml/snippet21.ml new file mode 100644 index 00000000..f63937b7 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet21.ml @@ -0,0 +1,8 @@ +module type CoProduct = sig + type a + type b + type c + + val i : a -> c + val j : b -> c +end diff --git a/src/content/1.5/code/ocaml/snippet22.ml b/src/content/1.5/code/ocaml/snippet22.ml new file mode 100644 index 00000000..927fb6a3 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet22.ml @@ -0,0 +1,2 @@ +i' == compose m i +j' == compose m j diff --git a/src/content/1.5/code/ocaml/snippet23.ml b/src/content/1.5/code/ocaml/snippet23.ml new file mode 100644 index 00000000..e3f11cba --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet23.ml @@ -0,0 +1,3 @@ +type contact = + | PhoneNum of int + | EmailAddr of string diff --git a/src/content/1.5/code/ocaml/snippet24.ml b/src/content/1.5/code/ocaml/snippet24.ml new file mode 100644 index 00000000..d99490ec --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet24.ml @@ -0,0 +1 @@ +let helpdesk = PhoneNum 2222222 diff --git a/src/content/1.5/code/ocaml/snippet25.ml b/src/content/1.5/code/ocaml/snippet25.ml new file mode 100644 index 00000000..0c0aff60 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet25.ml @@ -0,0 +1,3 @@ +type ('a, 'b) either = + | Left of 'a + | Right of 'b diff --git a/src/content/1.5/code/ocaml/snippet26.ml b/src/content/1.5/code/ocaml/snippet26.ml new file mode 100644 index 00000000..725e2a29 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet26.ml @@ -0,0 +1,4 @@ +let factorizer i j = function + | Left a -> i a + | Right b -> j b +;; diff --git a/src/content/1.5/code/ocaml/snippet27.ml b/src/content/1.5/code/ocaml/snippet27.ml new file mode 100644 index 00000000..5af299b5 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet27.ml @@ -0,0 +1,2 @@ +p = compose fst m +q = compose snd m diff --git a/src/content/1.5/code/ocaml/snippet28.ml b/src/content/1.5/code/ocaml/snippet28.ml new file mode 100644 index 00000000..e44ffb71 --- /dev/null +++ b/src/content/1.5/code/ocaml/snippet28.ml @@ -0,0 +1,2 @@ +p () = fst (m ()) +q () = snd (m ()) diff --git a/src/content/1.6/code/ocaml/snippet01.ml b/src/content/1.6/code/ocaml/snippet01.ml new file mode 100644 index 00000000..fd327462 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +let swap (a, b) = b, a diff --git a/src/content/1.6/code/ocaml/snippet02.ml b/src/content/1.6/code/ocaml/snippet02.ml new file mode 100644 index 00000000..ec4eea39 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +(('a * 'b) * 'c) diff --git a/src/content/1.6/code/ocaml/snippet03.ml b/src/content/1.6/code/ocaml/snippet03.ml new file mode 100644 index 00000000..e898fe52 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet03.ml @@ -0,0 +1 @@ +('a * ('b * 'c)) diff --git a/src/content/1.6/code/ocaml/snippet04.ml b/src/content/1.6/code/ocaml/snippet04.ml new file mode 100644 index 00000000..835c2570 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet04.ml @@ -0,0 +1 @@ +let alpha ((a, b), c) = a, (b, c) diff --git a/src/content/1.6/code/ocaml/snippet05.ml b/src/content/1.6/code/ocaml/snippet05.ml new file mode 100644 index 00000000..5efefd60 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +let alpha_inv (a, (b, c)) = (a, b), c diff --git a/src/content/1.6/code/ocaml/snippet06.ml b/src/content/1.6/code/ocaml/snippet06.ml new file mode 100644 index 00000000..ecac6b66 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +'a * unit diff --git a/src/content/1.6/code/ocaml/snippet07.ml b/src/content/1.6/code/ocaml/snippet07.ml new file mode 100644 index 00000000..8d6e1786 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +let rho (a, ()) = a diff --git a/src/content/1.6/code/ocaml/snippet08.ml b/src/content/1.6/code/ocaml/snippet08.ml new file mode 100644 index 00000000..ced50598 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +let rho_inv a = a, () diff --git a/src/content/1.6/code/ocaml/snippet09.ml b/src/content/1.6/code/ocaml/snippet09.ml new file mode 100644 index 00000000..defd1c1b --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet09.ml @@ -0,0 +1 @@ +type ('a, 'b) pair = P of 'a * 'b diff --git a/src/content/1.6/code/ocaml/snippet10.ml b/src/content/1.6/code/ocaml/snippet10.ml new file mode 100644 index 00000000..e8ac6545 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet10.ml @@ -0,0 +1 @@ +let stmt = P ("This statement is", false) diff --git a/src/content/1.6/code/ocaml/snippet11.ml b/src/content/1.6/code/ocaml/snippet11.ml new file mode 100644 index 00000000..666d874f --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet11.ml @@ -0,0 +1 @@ +type ('a, 'b) pair = Pair of ('a * 'b) diff --git a/src/content/1.6/code/ocaml/snippet12.ml b/src/content/1.6/code/ocaml/snippet12.ml new file mode 100644 index 00000000..8da12ccc --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet12.ml @@ -0,0 +1 @@ +let stmt = "This statement is", false diff --git a/src/content/1.6/code/ocaml/snippet13.ml b/src/content/1.6/code/ocaml/snippet13.ml new file mode 100644 index 00000000..5a55161d --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet13.ml @@ -0,0 +1 @@ +type stmt = Stmt of string * int diff --git a/src/content/1.6/code/ocaml/snippet14.ml b/src/content/1.6/code/ocaml/snippet14.ml new file mode 100644 index 00000000..9633b135 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet14.ml @@ -0,0 +1,3 @@ +let starts_with_symbol (name, symbol, _) = + String.is_prefix name ~prefix:symbol +;; diff --git a/src/content/1.6/code/ocaml/snippet15.ml b/src/content/1.6/code/ocaml/snippet15.ml new file mode 100644 index 00000000..cc409865 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet15.ml @@ -0,0 +1,5 @@ +type element = + { name : string + ; symbol : string + ; atomic_number : int + } diff --git a/src/content/1.6/code/ocaml/snippet16.ml b/src/content/1.6/code/ocaml/snippet16.ml new file mode 100644 index 00000000..f6a3f35c --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet16.ml @@ -0,0 +1,3 @@ +let tuple_to_elem (name, symbol, atomic_number) = + { name; symbol; atomic_number } +;; diff --git a/src/content/1.6/code/ocaml/snippet17.ml b/src/content/1.6/code/ocaml/snippet17.ml new file mode 100644 index 00000000..39838ded --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet17.ml @@ -0,0 +1,3 @@ +let elem_to_tuple { name; symbol; atomic_number } = + name, symbol, atomic_number +;; diff --git a/src/content/1.6/code/ocaml/snippet18.ml b/src/content/1.6/code/ocaml/snippet18.ml new file mode 100644 index 00000000..6f59b9ed --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet18.ml @@ -0,0 +1 @@ +let atomic_number { atomic_number } = atomic_number diff --git a/src/content/1.6/code/ocaml/snippet19.ml b/src/content/1.6/code/ocaml/snippet19.ml new file mode 100644 index 00000000..0e34acb2 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet19.ml @@ -0,0 +1,3 @@ +let starts_with_symbol { name; symbol; _ } = + String.is_prefix name ~prefix:symbol +;; diff --git a/src/content/1.6/code/ocaml/snippet20.ml b/src/content/1.6/code/ocaml/snippet20.ml new file mode 100644 index 00000000..1cf297ef --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet20.ml @@ -0,0 +1 @@ +(* OCaml only allows special characters in the infix operator. So, the above function name cannot be applied be infix. *) diff --git a/src/content/1.6/code/ocaml/snippet21.ml b/src/content/1.6/code/ocaml/snippet21.ml new file mode 100644 index 00000000..0c0aff60 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet21.ml @@ -0,0 +1,3 @@ +type ('a, 'b) either = + | Left of 'a + | Right of 'b diff --git a/src/content/1.6/code/ocaml/snippet22.ml b/src/content/1.6/code/ocaml/snippet22.ml new file mode 100644 index 00000000..f1a79e41 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet22.ml @@ -0,0 +1,4 @@ +type ('a, 'b, 'c) one_of_three = + | Sinistrial of 'a + | Medial of 'b + | Dextral of 'c diff --git a/src/content/1.6/code/ocaml/snippet23.ml b/src/content/1.6/code/ocaml/snippet23.ml new file mode 100644 index 00000000..36b070f0 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet23.ml @@ -0,0 +1 @@ +'a void either diff --git a/src/content/1.6/code/ocaml/snippet24.ml b/src/content/1.6/code/ocaml/snippet24.ml new file mode 100644 index 00000000..8c0c65f4 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet24.ml @@ -0,0 +1,4 @@ +type color = + | Red + | Green + | Blue diff --git a/src/content/1.6/code/ocaml/snippet25.ml b/src/content/1.6/code/ocaml/snippet25.ml new file mode 100644 index 00000000..1e1b0764 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet25.ml @@ -0,0 +1,3 @@ +type bool = + | True + | False diff --git a/src/content/1.6/code/ocaml/snippet26.ml b/src/content/1.6/code/ocaml/snippet26.ml new file mode 100644 index 00000000..b285a7df --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet26.ml @@ -0,0 +1,3 @@ +type 'a maybe = + | Nothing + | Just of 'a diff --git a/src/content/1.6/code/ocaml/snippet27.ml b/src/content/1.6/code/ocaml/snippet27.ml new file mode 100644 index 00000000..6c77da86 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet27.ml @@ -0,0 +1 @@ +type nothing_type = Nothing diff --git a/src/content/1.6/code/ocaml/snippet28.ml b/src/content/1.6/code/ocaml/snippet28.ml new file mode 100644 index 00000000..84fa905c --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet28.ml @@ -0,0 +1 @@ +type 'a just_type = Just of 'a diff --git a/src/content/1.6/code/ocaml/snippet29.ml b/src/content/1.6/code/ocaml/snippet29.ml new file mode 100644 index 00000000..765342f5 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet29.ml @@ -0,0 +1 @@ +type 'a maybe = (unit, 'a) either diff --git a/src/content/1.6/code/ocaml/snippet30.ml b/src/content/1.6/code/ocaml/snippet30.ml new file mode 100644 index 00000000..bf428a2a --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet30.ml @@ -0,0 +1,3 @@ +type 'a list = + | Nil + | Cons of 'a * 'a list diff --git a/src/content/1.6/code/ocaml/snippet31.ml b/src/content/1.6/code/ocaml/snippet31.ml new file mode 100644 index 00000000..f8b5575b --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet31.ml @@ -0,0 +1,8 @@ +type 'a maybe = + | Nothing + | Just of 'a + +let maybe_tail = function + | Nil -> Nothing + | Cons (_, xs) -> Just xs +;; diff --git a/src/content/1.6/code/ocaml/snippet32.ml b/src/content/1.6/code/ocaml/snippet32.ml new file mode 100644 index 00000000..32adf005 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet32.ml @@ -0,0 +1 @@ +'a * ('b, 'c) either diff --git a/src/content/1.6/code/ocaml/snippet33.ml b/src/content/1.6/code/ocaml/snippet33.ml new file mode 100644 index 00000000..1d5d5f3c --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet33.ml @@ -0,0 +1 @@ +('a * 'b, 'c * 'd) either diff --git a/src/content/1.6/code/ocaml/snippet34.ml b/src/content/1.6/code/ocaml/snippet34.ml new file mode 100644 index 00000000..6799f166 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet34.ml @@ -0,0 +1,5 @@ +let prod_to_sum (x, e) = + match e with + | Left y -> Left (x, y) + | Right z -> Right (x, z) +;; diff --git a/src/content/1.6/code/ocaml/snippet35.ml b/src/content/1.6/code/ocaml/snippet35.ml new file mode 100644 index 00000000..ab0d5482 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet35.ml @@ -0,0 +1,4 @@ +let sum_to_prod = function + | Left (x, y) -> x, Left y + | Right (x, z) -> x, Right z +;; diff --git a/src/content/1.6/code/ocaml/snippet36.ml b/src/content/1.6/code/ocaml/snippet36.ml new file mode 100644 index 00000000..e44d7fa2 --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet36.ml @@ -0,0 +1 @@ +let prod1 = 2, Left "Hi!" diff --git a/src/content/1.6/code/ocaml/snippet37.ml b/src/content/1.6/code/ocaml/snippet37.ml new file mode 100644 index 00000000..bf428a2a --- /dev/null +++ b/src/content/1.6/code/ocaml/snippet37.ml @@ -0,0 +1,3 @@ +type 'a list = + | Nil + | Cons of 'a * 'a list diff --git a/src/content/1.7/code/ocaml/snippet01.ml b/src/content/1.7/code/ocaml/snippet01.ml new file mode 100644 index 00000000..8c87a4e3 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +let compose f g x = f (g x) diff --git a/src/content/1.7/code/ocaml/snippet02.ml b/src/content/1.7/code/ocaml/snippet02.ml new file mode 100644 index 00000000..e30a56a0 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet02.ml @@ -0,0 +1,3 @@ +type 'a option = + | None + | Some of 'a diff --git a/src/content/1.7/code/ocaml/snippet03.ml b/src/content/1.7/code/ocaml/snippet03.ml new file mode 100644 index 00000000..35f307e9 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet03.ml @@ -0,0 +1,6 @@ +module type AtoB = sig + type a + type b + + val f : a -> b +end diff --git a/src/content/1.7/code/ocaml/snippet04.ml b/src/content/1.7/code/ocaml/snippet04.ml new file mode 100644 index 00000000..8103489d --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet04.ml @@ -0,0 +1,4 @@ +let f' f = function + | None -> None + | Some x -> Some (f x) +;; diff --git a/src/content/1.7/code/ocaml/snippet05.ml b/src/content/1.7/code/ocaml/snippet05.ml new file mode 100644 index 00000000..d6e711ee --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet05.ml @@ -0,0 +1,6 @@ +module type Maybe_Functor = sig + type a + type b + + val fmap : (a -> b) -> a option -> b option +end diff --git a/src/content/1.7/code/ocaml/snippet06.ml b/src/content/1.7/code/ocaml/snippet06.ml new file mode 100644 index 00000000..d6e711ee --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet06.ml @@ -0,0 +1,6 @@ +module type Maybe_Functor = sig + type a + type b + + val fmap : (a -> b) -> a option -> b option +end diff --git a/src/content/1.7/code/ocaml/snippet07.ml b/src/content/1.7/code/ocaml/snippet07.ml new file mode 100644 index 00000000..8137ae73 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet07.ml @@ -0,0 +1,4 @@ +let fmap f = function + | None -> None + | Some x -> Some (f x) +;; diff --git a/src/content/1.7/code/ocaml/snippet08.ml b/src/content/1.7/code/ocaml/snippet08.ml new file mode 100644 index 00000000..f54d47a8 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +let id x = x diff --git a/src/content/1.7/code/ocaml/snippet09.ml b/src/content/1.7/code/ocaml/snippet09.ml new file mode 100644 index 00000000..8605401a --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet09.ml @@ -0,0 +1,5 @@ +module Test_Functor_Id (F : Functor) = struct + open F + + let test_id x = assert (fmap id x = x) +end diff --git a/src/content/1.7/code/ocaml/snippet10.ml b/src/content/1.7/code/ocaml/snippet10.ml new file mode 100644 index 00000000..f2192316 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet10.ml @@ -0,0 +1,8 @@ +module Test_Functor_Compose(F: Functor) = struct + open F + + (* Compose *) + let <.> f g x = f (g x) + + let test_compose f g x = assert (fmap (f <.> g) x = fmap f (fmap g x)) +end diff --git a/src/content/1.7/code/ocaml/snippet11.ml b/src/content/1.7/code/ocaml/snippet11.ml new file mode 100644 index 00000000..d74faf41 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet11.ml @@ -0,0 +1,5 @@ +module type Eq = sig + type a + + val ( == ) : a -> a -> bool +end diff --git a/src/content/1.7/code/ocaml/snippet12.ml b/src/content/1.7/code/ocaml/snippet12.ml new file mode 100644 index 00000000..9dcde84a --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet12.ml @@ -0,0 +1 @@ +type point = Pt of float * float diff --git a/src/content/1.7/code/ocaml/snippet13.ml b/src/content/1.7/code/ocaml/snippet13.ml new file mode 100644 index 00000000..9e98baf9 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet13.ml @@ -0,0 +1,7 @@ +module Point_Eq (E : Eq with type a = float) = struct + type a = point + + let ( == ) (Pt (p1x, p1y)) (Pt (p2x, p2y)) = + E.(p1x == p2x) && E.(p2x == p2y) + ;; +end diff --git a/src/content/1.7/code/ocaml/snippet14.ml b/src/content/1.7/code/ocaml/snippet14.ml new file mode 100644 index 00000000..9aa9b8de --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet14.ml @@ -0,0 +1,5 @@ +module type Functor = sig + type 'a t + + val fmap : ('a -> 'b) -> 'a t -> 'b t +end diff --git a/src/content/1.7/code/ocaml/snippet15.ml b/src/content/1.7/code/ocaml/snippet15.ml new file mode 100644 index 00000000..dbd72adb --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet15.ml @@ -0,0 +1,8 @@ +module Option_Functor : Functor with type 'a t = 'a option = struct + type 'a t = 'a option + + let fmap f = function + | None -> None + | Some x -> Some (f x) + ;; +end diff --git a/src/content/1.7/code/ocaml/snippet16.ml b/src/content/1.7/code/ocaml/snippet16.ml new file mode 100644 index 00000000..bf428a2a --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet16.ml @@ -0,0 +1,3 @@ +type 'a list = + | Nil + | Cons of 'a * 'a list diff --git a/src/content/1.7/code/ocaml/snippet17.ml b/src/content/1.7/code/ocaml/snippet17.ml new file mode 100644 index 00000000..e9726a2b --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet17.ml @@ -0,0 +1,5 @@ +module type List_Functor_Type = sig + type 'a t = 'a list + + val fmap : ('a -> 'b) -> 'a list -> 'b list +end diff --git a/src/content/1.7/code/ocaml/snippet18.ml b/src/content/1.7/code/ocaml/snippet18.ml new file mode 100644 index 00000000..9dec73be --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet18.ml @@ -0,0 +1,3 @@ +let rec fmap f = function + | Nil -> Nil + | Cons (x, xs) -> Cons (f x, fmap f xs) diff --git a/src/content/1.7/code/ocaml/snippet19.ml b/src/content/1.7/code/ocaml/snippet19.ml new file mode 100644 index 00000000..c4169c4c --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet19.ml @@ -0,0 +1,8 @@ +module List_Functor : Functor with type 'a t = 'a list = struct + type 'a t = 'a list + + let rec fmap f = function + | Nil -> Nil + | Cons (x, xs) -> Cons (f x, fmap f xs) + ;; +end diff --git a/src/content/1.7/code/ocaml/snippet20.ml b/src/content/1.7/code/ocaml/snippet20.ml new file mode 100644 index 00000000..ee49d1eb --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet20.ml @@ -0,0 +1 @@ +type ('a, 'b) t = 'a -> 'b diff --git a/src/content/1.7/code/ocaml/snippet21.ml b/src/content/1.7/code/ocaml/snippet21.ml new file mode 100644 index 00000000..2bfed024 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet21.ml @@ -0,0 +1,7 @@ +module type T = sig + type t +end + +module Partially_Applied_FunctionType (T : T) = struct + type 'b t = T.t -> 'b +end diff --git a/src/content/1.7/code/ocaml/snippet22.ml b/src/content/1.7/code/ocaml/snippet22.ml new file mode 100644 index 00000000..44311c34 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet22.ml @@ -0,0 +1,3 @@ +module type Reader_Fmap_Example = sig + val fmap : ('a -> 'b) -> ('r -> 'a) -> 'r -> 'b +end diff --git a/src/content/1.7/code/ocaml/snippet23.ml b/src/content/1.7/code/ocaml/snippet23.ml new file mode 100644 index 00000000..b0d5cf60 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet23.ml @@ -0,0 +1,5 @@ +module Reader_Functor (T : T) : Functor = struct + type 'a t = T.t -> 'a + + let fmap f ra r = f (ra r) +end diff --git a/src/content/1.7/code/ocaml/snippet24.ml b/src/content/1.7/code/ocaml/snippet24.ml new file mode 100644 index 00000000..9b997d1c --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet24.ml @@ -0,0 +1 @@ +let fmap : ('a -> 'b) -> ('r -> 'a) -> 'r -> 'b = compose diff --git a/src/content/1.7/code/ocaml/snippet25.ml b/src/content/1.7/code/ocaml/snippet25.ml new file mode 100644 index 00000000..8b1f1ab6 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet25.ml @@ -0,0 +1 @@ +let nats = Caml.Stream.from (fun i -> Some (i + 1)) diff --git a/src/content/1.7/code/ocaml/snippet26.ml b/src/content/1.7/code/ocaml/snippet26.ml new file mode 100644 index 00000000..43d42412 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet26.ml @@ -0,0 +1 @@ +type ('c, 'a) const = Const of 'c diff --git a/src/content/1.7/code/ocaml/snippet27.ml b/src/content/1.7/code/ocaml/snippet27.ml new file mode 100644 index 00000000..6397b57b --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet27.ml @@ -0,0 +1,3 @@ +module type Const_Functor_Example = sig + val fmap : ('a -> 'b) -> ('c, 'a) const -> ('c, 'b) const +end diff --git a/src/content/1.7/code/ocaml/snippet28.ml b/src/content/1.7/code/ocaml/snippet28.ml new file mode 100644 index 00000000..d3ba51fb --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet28.ml @@ -0,0 +1,5 @@ +module Const_Functor (T : T) : Functor = struct + type 'a t = (T.t, 'a) const + + let fmap f (Const c) = Const c (* or even let fmap _ c = c *) +end diff --git a/src/content/1.7/code/ocaml/snippet29.ml b/src/content/1.7/code/ocaml/snippet29.ml new file mode 100644 index 00000000..956a98a8 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet29.ml @@ -0,0 +1,4 @@ +let maybe_tail = function + | [] -> None + | _ :: xs -> Some xs +;; diff --git a/src/content/1.7/code/ocaml/snippet30.ml b/src/content/1.7/code/ocaml/snippet30.ml new file mode 100644 index 00000000..8c4ac188 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet30.ml @@ -0,0 +1,3 @@ +let square x = x * x +let mis = Some (Cons (1, Cons (2, Cons (3, Nil)))) +let mis2 = Option_Functor.fmap (List_Functor.fmap square) mis diff --git a/src/content/1.7/code/ocaml/snippet31.ml b/src/content/1.7/code/ocaml/snippet31.ml new file mode 100644 index 00000000..bf03da02 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet31.ml @@ -0,0 +1,4 @@ +let fmapO = Option_Functor.fmap +let fmapL = List_Functor.fmap +let fmapC f l = (compose fmapO fmapL) f l +let mis2 = fmapC square mis diff --git a/src/content/1.7/code/ocaml/snippet32.ml b/src/content/1.7/code/ocaml/snippet32.ml new file mode 100644 index 00000000..d2c70402 --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet32.ml @@ -0,0 +1,5 @@ +module type Fmap_Alt_Sig_Example = sig + type 'a t + + val fmap : ('a -> 'b) -> 'a t -> 'b t +end diff --git a/src/content/1.7/code/ocaml/snippet33.ml b/src/content/1.7/code/ocaml/snippet33.ml new file mode 100644 index 00000000..6941c08e --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet33.ml @@ -0,0 +1,3 @@ +module type Square_Signature = sig + val square : int -> int +end diff --git a/src/content/1.7/code/ocaml/snippet34.ml b/src/content/1.7/code/ocaml/snippet34.ml new file mode 100644 index 00000000..0309b91a --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet34.ml @@ -0,0 +1 @@ +int list -> int list diff --git a/src/content/1.7/code/ocaml/snippet35.ml b/src/content/1.7/code/ocaml/snippet35.ml new file mode 100644 index 00000000..2072906a --- /dev/null +++ b/src/content/1.7/code/ocaml/snippet35.ml @@ -0,0 +1 @@ +int list option -> int list option diff --git a/src/content/1.8/code/ocaml/snippet01.ml b/src/content/1.8/code/ocaml/snippet01.ml new file mode 100644 index 00000000..050e23df --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet01.ml @@ -0,0 +1,28 @@ +(** You can represent bifunctor defintion in two forms and implement just and derive the other from it. *) +module type BifunctorCore = sig + type ('a, 'b) t + + val bimap : ('a -> 'c) -> ('b -> 'd) -> ('a, 'b) t -> ('c, 'd) t +end + +module type BifunctorExt = sig + type ('a, 'b) t + + val first : ('a -> 'c) -> ('a, 'b) t -> ('c, 'b) t + val second : ('b -> 'd) -> ('a, 'b) t -> ('a, 'd) t +end + +module BifunctorCore_Using_Ext (M : BifunctorExt) : BifunctorCore = +struct + type ('a, 'b) t = ('a, 'b) M.t + + let bimap g h x = M.first g (M.second h x) +end + +module BifunctorExt_Using_Core (M : BifunctorCore) : BifunctorExt = +struct + type ('a, 'b) t = ('a, 'b) M.t + + let first g x = M.bimap g id x + let second h x = M.bimap id h x +end diff --git a/src/content/1.8/code/ocaml/snippet02.ml b/src/content/1.8/code/ocaml/snippet02.ml new file mode 100644 index 00000000..1329dbb2 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet02.ml @@ -0,0 +1,5 @@ +module Bifunctor_Product : BifunctorCore = struct + type ('a, 'b) t = 'a * 'b + + let bimap f g (l, r) = f l, g r +end diff --git a/src/content/1.8/code/ocaml/snippet03.ml b/src/content/1.8/code/ocaml/snippet03.ml new file mode 100644 index 00000000..03f3798c --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet03.ml @@ -0,0 +1,5 @@ +val bimap + : ('a -> 'c) + -> ('b -> 'd) + -> ('a, 'b) Bifunctor_Product.t + -> ('c, 'd) Bifunctor_Product.t diff --git a/src/content/1.8/code/ocaml/snippet04.ml b/src/content/1.8/code/ocaml/snippet04.ml new file mode 100644 index 00000000..442cf6d8 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet04.ml @@ -0,0 +1,12 @@ +type ('a, 'b) either = + | Left of 'a + | Right of 'b + +module Bifunctor_Either : BifunctorCore = struct + type ('a, 'b) t = ('a, 'b) either + + let bimap f g = function + | Left a -> Left (f a) + | Right b -> Right (g b) + ;; +end diff --git a/src/content/1.8/code/ocaml/snippet05.ml b/src/content/1.8/code/ocaml/snippet05.ml new file mode 100644 index 00000000..eead2268 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +type 'a id = Id of 'a diff --git a/src/content/1.8/code/ocaml/snippet06.ml b/src/content/1.8/code/ocaml/snippet06.ml new file mode 100644 index 00000000..a97203ae --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet06.ml @@ -0,0 +1,5 @@ +module Identity_Functor : Functor = struct + type 'a t = 'a id + + let fmap f (Id a) = Id (f a) +end diff --git a/src/content/1.8/code/ocaml/snippet07.ml b/src/content/1.8/code/ocaml/snippet07.ml new file mode 100644 index 00000000..e30a56a0 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet07.ml @@ -0,0 +1,3 @@ +type 'a option = + | None + | Some of 'a diff --git a/src/content/1.8/code/ocaml/snippet08.ml b/src/content/1.8/code/ocaml/snippet08.ml new file mode 100644 index 00000000..ba64ba6f --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet08.ml @@ -0,0 +1,9 @@ +(** OCaml doesn't have a built in Const type *) +type ('a, 'b) const = Const of 'a + +(** OCaml doesn't have a built in either type *) +type ('a, 'b) either = + | Left of 'a + | Right of 'b (** Either type *) + +type 'a option = ((unit, 'a) const, 'a id) either diff --git a/src/content/1.8/code/ocaml/snippet09.ml b/src/content/1.8/code/ocaml/snippet09.ml new file mode 100644 index 00000000..d2f0eceb --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet09.ml @@ -0,0 +1,14 @@ +(** OCaml doesn't support higher kinded types. So, we have to use module functors to emulate the behavior higher kinded types. There's less verbose options using type defunctionalization but it's more advanced and obscures the flow of this book *) +module type BiComp = functor + (BF : sig + type ('a, 'b) t + end) + (FU : sig + type 'a t + end) + (GU : sig + type 'b t + end) + -> sig + type ('a, 'b) bicomp = BiComp of ('a FU.t, 'b GU.t) BF.t +end diff --git a/src/content/1.8/code/ocaml/snippet10.ml b/src/content/1.8/code/ocaml/snippet10.ml new file mode 100644 index 00000000..5029cdca --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet10.ml @@ -0,0 +1,10 @@ +module BiCompBifunctor + (BF : BifunctorCore) + (FU : Functor) + (GU : Functor) : BifunctorCore = struct + type ('a, 'b) t = BiComp of ('a FU.t, 'b GU.t) BF.t + + let bimap f g (BiComp x) = + BiComp (BF.bimap (FU.fmap f) (GU.fmap g) x) + ;; +end diff --git a/src/content/1.8/code/ocaml/snippet11.ml b/src/content/1.8/code/ocaml/snippet11.ml new file mode 100644 index 00000000..cdfa3789 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet11.ml @@ -0,0 +1 @@ +type ('a FU.t, 'b GU.t) BF.t diff --git a/src/content/1.8/code/ocaml/snippet12.ml b/src/content/1.8/code/ocaml/snippet12.ml new file mode 100644 index 00000000..820a6437 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet12.ml @@ -0,0 +1,2 @@ +val f1 : a -> a' +val f2 : b -> b' diff --git a/src/content/1.8/code/ocaml/snippet13.ml b/src/content/1.8/code/ocaml/snippet13.ml new file mode 100644 index 00000000..151bc9b0 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet13.ml @@ -0,0 +1 @@ +val bimap : (a FU.t -> a' FU.t) -> (b GU.t -> b' GU.t) -> (a FU.t, b GU.t) -> (a' FU.t, b' GU.t) diff --git a/src/content/1.8/code/ocaml/snippet14.ml b/src/content/1.8/code/ocaml/snippet14.ml new file mode 100644 index 00000000..b6bc4faf --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet14.ml @@ -0,0 +1,4 @@ +(** Deriving a functor in OCaml is not available as a language extension. You could try experimental library like ocsigen to derive functors.*) +type 'a tree = + | Leaf of 'a + | Node of 'a tree * 'a tree diff --git a/src/content/1.8/code/ocaml/snippet15.ml b/src/content/1.8/code/ocaml/snippet15.ml new file mode 100644 index 00000000..3f37dd43 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet15.ml @@ -0,0 +1,8 @@ +module TreeFunctor : Functor = struct + type 'a t = 'a tree + + let rec fmap f = function + | Leaf a -> Leaf (f a) + | Node (l, r) -> Node (fmap f l, fmap f r) + ;; +end diff --git a/src/content/1.8/code/ocaml/snippet16.ml b/src/content/1.8/code/ocaml/snippet16.ml new file mode 100644 index 00000000..6474dfa7 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet16.ml @@ -0,0 +1 @@ +type 'a writer = 'a * string diff --git a/src/content/1.8/code/ocaml/snippet17.ml b/src/content/1.8/code/ocaml/snippet17.ml new file mode 100644 index 00000000..0c2bae22 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet17.ml @@ -0,0 +1,10 @@ +module KleisliComposition = struct + let ( >=> ) + : ('a -> 'b writer) -> ('b -> 'c writer) -> 'a -> 'c writer + = + fun m1 m2 x -> + let y, s1 = m1 x in + let z, s2 = m2 y in + z, StringLabels.concat ~sep:"" [ s1; s2 ] + ;; +end diff --git a/src/content/1.8/code/ocaml/snippet18.ml b/src/content/1.8/code/ocaml/snippet18.ml new file mode 100644 index 00000000..cac9283e --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet18.ml @@ -0,0 +1,3 @@ +module KleisliIdentity = struct + let return : 'a -> 'a writer = fun a -> a, "" +end diff --git a/src/content/1.8/code/ocaml/snippet19.ml b/src/content/1.8/code/ocaml/snippet19.ml new file mode 100644 index 00000000..593e2aa1 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet19.ml @@ -0,0 +1,8 @@ +module KleisliFunctor : Functor = struct + type 'a t = 'a writer + + let fmap f = + KleisliComposition.( >=> ) id (fun x -> + KleisliIdentity.return (f x)) + ;; +end diff --git a/src/content/1.8/code/ocaml/snippet20.ml b/src/content/1.8/code/ocaml/snippet20.ml new file mode 100644 index 00000000..11dfcc47 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet20.ml @@ -0,0 +1,6 @@ +module PartialArrow (T : sig + type r +end) = +struct + type 'a t = T.r -> 'a +end diff --git a/src/content/1.8/code/ocaml/snippet21.ml b/src/content/1.8/code/ocaml/snippet21.ml new file mode 100644 index 00000000..74183eeb --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet21.ml @@ -0,0 +1 @@ +type ('r, 'a) reader = 'r -> 'a diff --git a/src/content/1.8/code/ocaml/snippet22.ml b/src/content/1.8/code/ocaml/snippet22.ml new file mode 100644 index 00000000..795b20bb --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet22.ml @@ -0,0 +1,7 @@ +module ReaderFunctor (In : sig + type r +end) : Functor = struct + type 'a t = (In.r, 'a) reader + + let fmap f g = compose f g +end diff --git a/src/content/1.8/code/ocaml/snippet23.ml b/src/content/1.8/code/ocaml/snippet23.ml new file mode 100644 index 00000000..c9fdb18b --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet23.ml @@ -0,0 +1 @@ +type ('r, 'a) op = 'a -> 'r diff --git a/src/content/1.8/code/ocaml/snippet24.ml b/src/content/1.8/code/ocaml/snippet24.ml new file mode 100644 index 00000000..37207ac3 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet24.ml @@ -0,0 +1 @@ +val fmap : 'a 'b. ('a -> 'b) -> ('a -> 'r) -> ('b -> 'r) diff --git a/src/content/1.8/code/ocaml/snippet25.ml b/src/content/1.8/code/ocaml/snippet25.ml new file mode 100644 index 00000000..632abad6 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet25.ml @@ -0,0 +1,5 @@ +module type Contravariant = sig + type 'a t + + val contramap : ('b -> 'a) -> 'a t -> 'b t +end diff --git a/src/content/1.8/code/ocaml/snippet26.ml b/src/content/1.8/code/ocaml/snippet26.ml new file mode 100644 index 00000000..bc942bff --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet26.ml @@ -0,0 +1,7 @@ +module OpContravariant (In : sig + type r +end) : Contravariant = struct + type 'a t = (In.r, 'a) op + + let contramap f g = compose g f +end diff --git a/src/content/1.8/code/ocaml/snippet27.ml b/src/content/1.8/code/ocaml/snippet27.ml new file mode 100644 index 00000000..6231f96b --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet27.ml @@ -0,0 +1 @@ +let flip f b a = f a b diff --git a/src/content/1.8/code/ocaml/snippet28.ml b/src/content/1.8/code/ocaml/snippet28.ml new file mode 100644 index 00000000..951687c2 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet28.ml @@ -0,0 +1,3 @@ +let contramap : ('b -> 'a) -> ('r, 'a) op -> ('r, 'b) op = + fun f g -> flip compose f g +;; diff --git a/src/content/1.8/code/ocaml/snippet29.ml b/src/content/1.8/code/ocaml/snippet29.ml new file mode 100644 index 00000000..7d368c55 --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet29.ml @@ -0,0 +1,30 @@ +(* Profunctor definition *) +module type Profunctor = sig + type ('a, 'b) p + + val dimap : ('a -> 'b) -> ('c -> 'd) -> ('b, 'c) p -> ('a, 'd) p +end + +(* Profunctor alternate definition *) +module type ProfunctorExt = sig + type ('a, 'b) p + + val lmap : ('a -> 'b) -> ('b, 'c) p -> ('a, 'c) p + val rmap : ('b -> 'c) -> ('a, 'b) p -> ('a, 'c) p +end + +(* Profunctor dimap defined using lmap and rmap *) +module Profunctor_Using_Ext (PF : ProfunctorExt) : Profunctor = struct + type ('a, 'b) p = ('a, 'b) PF.p + + let dimap f g = compose (PF.lmap f) (PF.rmap g) +end + +(** Profunctor lmap and rmap defined using dimap *) +module ProfunctorExt_Using_Dimap (PF : Profunctor) : ProfunctorExt = +struct + type ('a, 'b) p = ('a, 'b) PF.p + + let lmap f = PF.dimap f id + let rmap g = PF.dimap id g +end diff --git a/src/content/1.8/code/ocaml/snippet30.ml b/src/content/1.8/code/ocaml/snippet30.ml new file mode 100644 index 00000000..a05762ba --- /dev/null +++ b/src/content/1.8/code/ocaml/snippet30.ml @@ -0,0 +1,12 @@ +module ProfunctorArrow : Profunctor = struct + type ('a, 'b) p = 'a -> 'b + + let dimap f g p = compose g (compose p f) +end + +module ProfunctorExtArrow : ProfunctorExt = struct + type ('a, 'b) p = 'a -> 'b + + let lmap f p = (flip compose) f p + let rmap = compose +end diff --git a/src/content/1.9/code/ocaml/snippet01.ml b/src/content/1.9/code/ocaml/snippet01.ml new file mode 100644 index 00000000..2eb81298 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +'a -> ('b -> 'c) diff --git a/src/content/1.9/code/ocaml/snippet02.ml b/src/content/1.9/code/ocaml/snippet02.ml new file mode 100644 index 00000000..1f172aa3 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +'a -> 'b -> 'c diff --git a/src/content/1.9/code/ocaml/snippet03.ml b/src/content/1.9/code/ocaml/snippet03.ml new file mode 100644 index 00000000..29e124c5 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet03.ml @@ -0,0 +1 @@ +let catstr s s' = String.concat ~sep:"" [ s; s' ] diff --git a/src/content/1.9/code/ocaml/snippet04.ml b/src/content/1.9/code/ocaml/snippet04.ml new file mode 100644 index 00000000..29e124c5 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet04.ml @@ -0,0 +1 @@ +let catstr s s' = String.concat ~sep:"" [ s; s' ] diff --git a/src/content/1.9/code/ocaml/snippet05.ml b/src/content/1.9/code/ocaml/snippet05.ml new file mode 100644 index 00000000..475b5b5d --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +let greet = catstr "Hello" diff --git a/src/content/1.9/code/ocaml/snippet06.ml b/src/content/1.9/code/ocaml/snippet06.ml new file mode 100644 index 00000000..9eced4f7 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +'a * 'b -> 'a diff --git a/src/content/1.9/code/ocaml/snippet07.ml b/src/content/1.9/code/ocaml/snippet07.ml new file mode 100644 index 00000000..80b6a1cd --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +let curry f a b = f (a, b) diff --git a/src/content/1.9/code/ocaml/snippet08.ml b/src/content/1.9/code/ocaml/snippet08.ml new file mode 100644 index 00000000..dbb79205 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +let uncurry f p = f (fst p) (snd p) diff --git a/src/content/1.9/code/ocaml/snippet09.ml b/src/content/1.9/code/ocaml/snippet09.ml new file mode 100644 index 00000000..0632d1a6 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet09.ml @@ -0,0 +1 @@ +let factorizer g a b = g (a, b) diff --git a/src/content/1.9/code/ocaml/snippet10.ml b/src/content/1.9/code/ocaml/snippet10.ml new file mode 100644 index 00000000..9fd6dd07 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet10.ml @@ -0,0 +1,3 @@ +module type Exponential_Of_Sums_Example = sig + val f : (int, float) either -> string +end diff --git a/src/content/1.9/code/ocaml/snippet11.ml b/src/content/1.9/code/ocaml/snippet11.ml new file mode 100644 index 00000000..0de55132 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet11.ml @@ -0,0 +1,9 @@ +module Exp_Sum_Impl : Exponential_Of_Sums_Example = struct + let f = function + | Left n -> if n < 0 then "Negative int" else "Positive int" + | Right x -> + if Float.compare x 0.4 < 0 + then "Negative double" + else "Positive double" + ;; +end diff --git a/src/content/1.9/code/ocaml/snippet12.ml b/src/content/1.9/code/ocaml/snippet12.ml new file mode 100644 index 00000000..99195f96 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet12.ml @@ -0,0 +1 @@ +val eval : (('a -> 'b), 'a) -> 'b diff --git a/src/content/1.9/code/ocaml/snippet13.ml b/src/content/1.9/code/ocaml/snippet13.ml new file mode 100644 index 00000000..e67277a1 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet13.ml @@ -0,0 +1 @@ +let eval (f, a) = f a diff --git a/src/content/1.9/code/ocaml/snippet14.ml b/src/content/1.9/code/ocaml/snippet14.ml new file mode 100644 index 00000000..641b8e93 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet14.ml @@ -0,0 +1 @@ +('a, 'b) either -> 'a diff --git a/src/content/1.9/code/ocaml/snippet15.ml b/src/content/1.9/code/ocaml/snippet15.ml new file mode 100644 index 00000000..56309923 --- /dev/null +++ b/src/content/1.9/code/ocaml/snippet15.ml @@ -0,0 +1 @@ +val absurd : void -> 'a diff --git a/src/content/2.1/code/ocaml/snippet01.ml b/src/content/2.1/code/ocaml/snippet01.ml new file mode 100644 index 00000000..51102376 --- /dev/null +++ b/src/content/2.1/code/ocaml/snippet01.ml @@ -0,0 +1,2 @@ +(* Assume g and f are already defined *) +let h = compose g f diff --git a/src/content/2.1/code/ocaml/snippet02.ml b/src/content/2.1/code/ocaml/snippet02.ml new file mode 100644 index 00000000..54dab9c2 --- /dev/null +++ b/src/content/2.1/code/ocaml/snippet02.ml @@ -0,0 +1,4 @@ +let h x = + let y = f x in + g y +;; diff --git a/src/content/2.2/code/ocaml/snippet01.ml b/src/content/2.2/code/ocaml/snippet01.ml new file mode 100644 index 00000000..223fd022 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet01.ml @@ -0,0 +1,2 @@ +let p1 = compose p m +let q1 = compose q m diff --git a/src/content/2.2/code/ocaml/snippet02.ml b/src/content/2.2/code/ocaml/snippet02.ml new file mode 100644 index 00000000..38d99345 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet02.ml @@ -0,0 +1,4 @@ +let contramap : ('c_prime -> 'c) -> ('c -> 'limD) -> 'c_prime -> 'limD + = + fun f u -> compose u f +;; diff --git a/src/content/2.2/code/ocaml/snippet03.ml b/src/content/2.2/code/ocaml/snippet03.ml new file mode 100644 index 00000000..8861a992 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet03.ml @@ -0,0 +1,2 @@ +val f : 'a -> 'b +val g : 'a -> 'b diff --git a/src/content/2.2/code/ocaml/snippet04.ml b/src/content/2.2/code/ocaml/snippet04.ml new file mode 100644 index 00000000..847c21af --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet04.ml @@ -0,0 +1,2 @@ +val p : 'c -> 'a +val q : 'c -> 'b diff --git a/src/content/2.2/code/ocaml/snippet05.ml b/src/content/2.2/code/ocaml/snippet05.ml new file mode 100644 index 00000000..5680d1e9 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet05.ml @@ -0,0 +1,2 @@ +q = compose f p +q = compose g p diff --git a/src/content/2.2/code/ocaml/snippet06.ml b/src/content/2.2/code/ocaml/snippet06.ml new file mode 100644 index 00000000..ca027737 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet06.ml @@ -0,0 +1,2 @@ +(** Pseudo OCaml expressing function equality **) +compose f p = compose g p diff --git a/src/content/2.2/code/ocaml/snippet07.ml b/src/content/2.2/code/ocaml/snippet07.ml new file mode 100644 index 00000000..387fd907 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet07.ml @@ -0,0 +1,2 @@ +let f (x, y) = (2 * y) + x +let g (x, y) = y - x diff --git a/src/content/2.2/code/ocaml/snippet08.ml b/src/content/2.2/code/ocaml/snippet08.ml new file mode 100644 index 00000000..7f6be54d --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +let p t = t, -2 * t diff --git a/src/content/2.2/code/ocaml/snippet09.ml b/src/content/2.2/code/ocaml/snippet09.ml new file mode 100644 index 00000000..adf85c5a --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet09.ml @@ -0,0 +1,2 @@ +(** Pseudo OCaml expressing function equality **) +compose f p' = compose g p' diff --git a/src/content/2.2/code/ocaml/snippet10.ml b/src/content/2.2/code/ocaml/snippet10.ml new file mode 100644 index 00000000..fa731c1a --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet10.ml @@ -0,0 +1 @@ +let p' () = 0, 0 diff --git a/src/content/2.2/code/ocaml/snippet11.ml b/src/content/2.2/code/ocaml/snippet11.ml new file mode 100644 index 00000000..b18ca8f4 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet11.ml @@ -0,0 +1 @@ +let p' = compose p h diff --git a/src/content/2.2/code/ocaml/snippet12.ml b/src/content/2.2/code/ocaml/snippet12.ml new file mode 100644 index 00000000..e0d8b2a3 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet12.ml @@ -0,0 +1 @@ +let h () = 0 diff --git a/src/content/2.2/code/ocaml/snippet13.ml b/src/content/2.2/code/ocaml/snippet13.ml new file mode 100644 index 00000000..af6d4e06 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet13.ml @@ -0,0 +1,2 @@ +val f : 'a -> 'b +val g : 'c -> 'b diff --git a/src/content/2.2/code/ocaml/snippet14.ml b/src/content/2.2/code/ocaml/snippet14.ml new file mode 100644 index 00000000..1c304594 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet14.ml @@ -0,0 +1,3 @@ +val p : 'd -> 'a +val q : 'd -> 'c +val r : 'd -> 'b diff --git a/src/content/2.2/code/ocaml/snippet15.ml b/src/content/2.2/code/ocaml/snippet15.ml new file mode 100644 index 00000000..92804895 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet15.ml @@ -0,0 +1 @@ +compose g q = compose f p diff --git a/src/content/2.2/code/ocaml/snippet16.ml b/src/content/2.2/code/ocaml/snippet16.ml new file mode 100644 index 00000000..10df7cf6 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet16.ml @@ -0,0 +1 @@ +let f x = 1.23 diff --git a/src/content/2.2/code/ocaml/snippet17.ml b/src/content/2.2/code/ocaml/snippet17.ml new file mode 100644 index 00000000..d9f237c0 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet17.ml @@ -0,0 +1,13 @@ +module type Contravariant = sig + type 'a t + + val contramap : ('b -> 'a) -> 'a t -> 'b t +end + +type 'a tostring = ToString of ('a -> string) + +module ToStringInstance : Contravariant = struct + type 'a t = 'a tostring + + let contramap f (ToString g) = ToString (compose g f) +end diff --git a/src/content/2.2/code/ocaml/snippet18.ml b/src/content/2.2/code/ocaml/snippet18.ml new file mode 100644 index 00000000..37f14061 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet18.ml @@ -0,0 +1 @@ +('b 'c either) tostring ~ ('b -> string, 'c -> string) diff --git a/src/content/2.2/code/ocaml/snippet19.ml b/src/content/2.2/code/ocaml/snippet19.ml new file mode 100644 index 00000000..9a0c9db7 --- /dev/null +++ b/src/content/2.2/code/ocaml/snippet19.ml @@ -0,0 +1 @@ +'r -> ('a, 'b) ~ ('r -> 'a, 'r -> 'b) diff --git a/src/content/2.3/code/ocaml/snippet01.ml b/src/content/2.3/code/ocaml/snippet01.ml new file mode 100644 index 00000000..2642b264 --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet01.ml @@ -0,0 +1,6 @@ +module type Monoid = sig + type m + + val mempty : m + val mappend : m -> m -> m +end diff --git a/src/content/2.3/code/ocaml/snippet02.ml b/src/content/2.3/code/ocaml/snippet02.ml new file mode 100644 index 00000000..11549d28 --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet02.ml @@ -0,0 +1,8 @@ +module ListMonoid (T1 : sig + type a +end) : Monoid with type m = T1.a list = struct + type m = T1.a list + + let mempty = [] + let mappend xs ys = List.append xs ys +end diff --git a/src/content/2.3/code/ocaml/snippet03.ml b/src/content/2.3/code/ocaml/snippet03.ml new file mode 100644 index 00000000..fa4e639b --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet03.ml @@ -0,0 +1,2 @@ +2 * 3 = 6 +List.append [2] [3] = [2; 3] diff --git a/src/content/2.3/code/ocaml/snippet04.ml b/src/content/2.3/code/ocaml/snippet04.ml new file mode 100644 index 00000000..fd024d05 --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet04.ml @@ -0,0 +1 @@ +let h (a * b) = h a * h b diff --git a/src/content/2.3/code/ocaml/snippet05.ml b/src/content/2.3/code/ocaml/snippet05.ml new file mode 100644 index 00000000..694a1e55 --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +List.append [2] [3] = [2; 3] diff --git a/src/content/2.3/code/ocaml/snippet06.ml b/src/content/2.3/code/ocaml/snippet06.ml new file mode 100644 index 00000000..fe292af0 --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +2 * 3 = 6 diff --git a/src/content/2.3/code/ocaml/snippet07.ml b/src/content/2.3/code/ocaml/snippet07.ml new file mode 100644 index 00000000..7e653b45 --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet07.ml @@ -0,0 +1,6 @@ +module type FreeMonoidRep = functor (F : Functor) -> sig + type x + type m + + val p : x -> m F.t +end diff --git a/src/content/2.3/code/ocaml/snippet08.ml b/src/content/2.3/code/ocaml/snippet08.ml new file mode 100644 index 00000000..26b5f8f8 --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet08.ml @@ -0,0 +1,6 @@ +module type FreeMonoidRep = functor (F : Functor) -> sig + type x + type n + + val q : x -> n F.t +end diff --git a/src/content/2.3/code/ocaml/snippet09.ml b/src/content/2.3/code/ocaml/snippet09.ml new file mode 100644 index 00000000..ec5b3611 --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet09.ml @@ -0,0 +1 @@ +val h : m -> n diff --git a/src/content/2.3/code/ocaml/snippet10.ml b/src/content/2.3/code/ocaml/snippet10.ml new file mode 100644 index 00000000..f1ffddbb --- /dev/null +++ b/src/content/2.3/code/ocaml/snippet10.ml @@ -0,0 +1 @@ +val q = compose uh p diff --git a/src/content/2.4/code/ocaml/snippet01.ml b/src/content/2.4/code/ocaml/snippet01.ml new file mode 100644 index 00000000..1465fc2a --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +type ('a, 'x) reader = 'a -> 'x diff --git a/src/content/2.4/code/ocaml/snippet02.ml b/src/content/2.4/code/ocaml/snippet02.ml new file mode 100644 index 00000000..8b9d63b2 --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet02.ml @@ -0,0 +1,7 @@ +module ReaderFunctor (T : sig + type r +end) : Functor = struct + type 'a t = (T.r, 'a) reader + + let fmap f h a = f (h a) +end diff --git a/src/content/2.4/code/ocaml/snippet03.ml b/src/content/2.4/code/ocaml/snippet03.ml new file mode 100644 index 00000000..c7b3bfa4 --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet03.ml @@ -0,0 +1 @@ +type ('a, 'x) op = 'x -> 'a diff --git a/src/content/2.4/code/ocaml/snippet04.ml b/src/content/2.4/code/ocaml/snippet04.ml new file mode 100644 index 00000000..ba8a193c --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet04.ml @@ -0,0 +1,7 @@ +module OpContravariant (T : sig + type r +end) : Contravariant = struct + type 'a t = (T.r, 'a) op + + let contramap f h b = h (f b) +end diff --git a/src/content/2.4/code/ocaml/snippet05.ml b/src/content/2.4/code/ocaml/snippet05.ml new file mode 100644 index 00000000..f54ef523 --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet05.ml @@ -0,0 +1,7 @@ +module ProfunctorArrow : Profunctor = struct + type ('a, 'b) p = 'a -> 'b + + let dimap f g p = compose g (compose p f) + let lmap f p = (flip compose) f p + let rmap = compose +end diff --git a/src/content/2.4/code/ocaml/snippet06.ml b/src/content/2.4/code/ocaml/snippet06.ml new file mode 100644 index 00000000..b6c742bf --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet06.ml @@ -0,0 +1,6 @@ +module type NT_AX_FX = sig + type a + type 'x t + + val alpha : (a -> 'x) -> 'x t +end diff --git a/src/content/2.4/code/ocaml/snippet07.ml b/src/content/2.4/code/ocaml/snippet07.ml new file mode 100644 index 00000000..80888385 --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +compose (F.fmap f) NT.alpha = compose NT.alpha (F.fmap f) diff --git a/src/content/2.4/code/ocaml/snippet08.ml b/src/content/2.4/code/ocaml/snippet08.ml new file mode 100644 index 00000000..4d3519fb --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +F.fmap f (N.alpha h) = N.alpha (compose f h) diff --git a/src/content/2.4/code/ocaml/snippet09.ml b/src/content/2.4/code/ocaml/snippet09.ml new file mode 100644 index 00000000..041a32d6 --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet09.ml @@ -0,0 +1,6 @@ +module type NT_FX_AX = sig + type a + type 'x t + + val beta : 'x t -> a -> 'x +end diff --git a/src/content/2.4/code/ocaml/snippet10.ml b/src/content/2.4/code/ocaml/snippet10.ml new file mode 100644 index 00000000..f89f76cd --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet10.ml @@ -0,0 +1,7 @@ +module NT_Impl (F : Functor with type 'a t = 'a list) : + NT_AX_FX with type a = int and type 'x t = 'x list = struct + type a = int + type 'x t = 'x list + + let alpha : 'x. (int -> 'x) -> 'x list = fun h -> F.fmap h [ 12 ] +end diff --git a/src/content/2.4/code/ocaml/snippet11.ml b/src/content/2.4/code/ocaml/snippet11.ml new file mode 100644 index 00000000..5388056f --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet11.ml @@ -0,0 +1 @@ +F.fmap f (F.fmap h [12]) = F.fmap (compose f h) [12] diff --git a/src/content/2.4/code/ocaml/snippet12.ml b/src/content/2.4/code/ocaml/snippet12.ml new file mode 100644 index 00000000..0f93e425 --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet12.ml @@ -0,0 +1,6 @@ +module type NT_ListX_IntX = sig + type a = int + type 'x t = 'x list + + val beta : 'x t -> a -> 'x +end diff --git a/src/content/2.4/code/ocaml/snippet13.ml b/src/content/2.4/code/ocaml/snippet13.ml new file mode 100644 index 00000000..8c313008 --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet13.ml @@ -0,0 +1,7 @@ +module type Representable = sig + type 'x t + type rep (* Representing type 'a' *) + + val tabulate : (rep -> 'x) -> 'x t + val index : 'x t -> rep -> 'x +end diff --git a/src/content/2.4/code/ocaml/snippet14.ml b/src/content/2.4/code/ocaml/snippet14.ml new file mode 100644 index 00000000..4d0a3169 --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet14.ml @@ -0,0 +1 @@ +type 'a stream = Cons of 'a * 'a stream Lazy.t diff --git a/src/content/2.4/code/ocaml/snippet15.ml b/src/content/2.4/code/ocaml/snippet15.ml new file mode 100644 index 00000000..10a5351d --- /dev/null +++ b/src/content/2.4/code/ocaml/snippet15.ml @@ -0,0 +1,10 @@ +module StreamRepresentable : Representable = struct + type rep = int + type 'x t = 'x stream + + let rec tabulate f = Cons (f 0, lazy (tabulate (compose f succ))) + + let rec index (Cons (b, bs)) n = + if n = 0 then b else index (Lazy.force bs) (n - 1) + ;; +end diff --git a/src/content/2.5/code/ocaml/snippet01.ml b/src/content/2.5/code/ocaml/snippet01.ml new file mode 100644 index 00000000..1465fc2a --- /dev/null +++ b/src/content/2.5/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +type ('a, 'x) reader = 'a -> 'x diff --git a/src/content/2.5/code/ocaml/snippet02.ml b/src/content/2.5/code/ocaml/snippet02.ml new file mode 100644 index 00000000..3ea94519 --- /dev/null +++ b/src/content/2.5/code/ocaml/snippet02.ml @@ -0,0 +1,7 @@ +module ReaderFunctor (T : sig + type a +end) : Functor = struct + type 'x t = (T.a, 'x) reader + + let fmap : ('x -> 'y) -> 'x t -> 'y t = fun f r a -> f (r a) +end diff --git a/src/content/2.5/code/ocaml/snippet03.ml b/src/content/2.5/code/ocaml/snippet03.ml new file mode 100644 index 00000000..b6c742bf --- /dev/null +++ b/src/content/2.5/code/ocaml/snippet03.ml @@ -0,0 +1,6 @@ +module type NT_AX_FX = sig + type a + type 'x t + + val alpha : (a -> 'x) -> 'x t +end diff --git a/src/content/2.5/code/ocaml/snippet04.ml b/src/content/2.5/code/ocaml/snippet04.ml new file mode 100644 index 00000000..136c91ef --- /dev/null +++ b/src/content/2.5/code/ocaml/snippet04.ml @@ -0,0 +1 @@ +val alpha : (a -> 'x) -> 'x t diff --git a/src/content/2.5/code/ocaml/snippet05.ml b/src/content/2.5/code/ocaml/snippet05.ml new file mode 100644 index 00000000..4dee2fa2 --- /dev/null +++ b/src/content/2.5/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +alpha id : 'a f diff --git a/src/content/2.5/code/ocaml/snippet06.ml b/src/content/2.5/code/ocaml/snippet06.ml new file mode 100644 index 00000000..1e4350d0 --- /dev/null +++ b/src/content/2.5/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +val fa : 'a f diff --git a/src/content/2.5/code/ocaml/snippet07.ml b/src/content/2.5/code/ocaml/snippet07.ml new file mode 100644 index 00000000..87d82e6e --- /dev/null +++ b/src/content/2.5/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +alpha h = F.fmap h fa diff --git a/src/content/2.6/code/ocaml/snippet01.ml b/src/content/2.6/code/ocaml/snippet01.ml new file mode 100644 index 00000000..13d39cfb --- /dev/null +++ b/src/content/2.6/code/ocaml/snippet01.ml @@ -0,0 +1,11 @@ +module type BtoA = sig + type a + type b + + val btoa : b -> a +end + +(* Define the Yoneda embedding *) +module Yoneda_Embedding (E : BtoA) = struct + let fromY : 'x. (E.a -> 'x) -> E.b -> 'x = fun f b -> f (E.btoa b) +end diff --git a/src/content/2.6/code/ocaml/snippet02.ml b/src/content/2.6/code/ocaml/snippet02.ml new file mode 100644 index 00000000..b287444b --- /dev/null +++ b/src/content/2.6/code/ocaml/snippet02.ml @@ -0,0 +1,2 @@ +module YE = Yoneda_Embedding(BtoAImpl) +YE.fromY id (* output type : BtoA.b -> BtoA.a *) diff --git a/src/content/3.10/code/ocaml/snippet01.ml b/src/content/3.10/code/ocaml/snippet01.ml new file mode 100644 index 00000000..0acb6503 --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet01.ml @@ -0,0 +1,13 @@ +module type Functor = sig + type 'a t + + val fmap : ('a -> 'b) -> 'a t -> 'b t +end + +module type Profunctor = sig + type ('a, 'b) p + + val dimap : ('c -> 'a) -> ('b -> 'd) -> ('a, 'b) p -> ('c, 'd) p +end + +let id a = a diff --git a/src/content/3.10/code/ocaml/snippet02.ml b/src/content/3.10/code/ocaml/snippet02.ml new file mode 100644 index 00000000..cf511509 --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +let dimap f id (P (b, b)) : ('a, 'b) p diff --git a/src/content/3.10/code/ocaml/snippet03.ml b/src/content/3.10/code/ocaml/snippet03.ml new file mode 100644 index 00000000..90ec92ad --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet03.ml @@ -0,0 +1 @@ +let dimap id f (P (a, a)) : ('a, 'b) p diff --git a/src/content/3.10/code/ocaml/snippet04.ml b/src/content/3.10/code/ocaml/snippet04.ml new file mode 100644 index 00000000..4a8d89de --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet04.ml @@ -0,0 +1,4 @@ +(* There is no compose operator in OCaml *) + +;; +compose (dimap id f) alpha = compose (dimap f id) alpha diff --git a/src/content/3.10/code/ocaml/snippet05.ml b/src/content/3.10/code/ocaml/snippet05.ml new file mode 100644 index 00000000..2f9b83fd --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +'a. ('a, 'a) p diff --git a/src/content/3.10/code/ocaml/snippet06.ml b/src/content/3.10/code/ocaml/snippet06.ml new file mode 100644 index 00000000..fe9e8d6c --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet06.ml @@ -0,0 +1,2 @@ +;; +compose (dimap f id) pi = compose (dimap id f) pi diff --git a/src/content/3.10/code/ocaml/snippet07.ml b/src/content/3.10/code/ocaml/snippet07.ml new file mode 100644 index 00000000..a42d0a27 --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet07.ml @@ -0,0 +1,5 @@ +module type Polymorphic_Projection = functor (P : Profunctor) -> sig + type rank2_p = { p : 'c. ('c, 'c) P.p } + + val pi : rank2_p -> ('a, 'b) P.p +end diff --git a/src/content/3.10/code/ocaml/snippet08.ml b/src/content/3.10/code/ocaml/snippet08.ml new file mode 100644 index 00000000..010af1fa --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet08.ml @@ -0,0 +1,5 @@ +module Pi (P : Profunctor) = struct + type rank2_p = { p : 'a. ('a, 'a) P.p } + + let pi : rank2_p -> ('c, 'c) P.p = fun e -> e.p +end diff --git a/src/content/3.10/code/ocaml/snippet09.ml b/src/content/3.10/code/ocaml/snippet09.ml new file mode 100644 index 00000000..d9f7f77e --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet09.ml @@ -0,0 +1,9 @@ +module EndsEqualizer (P : Profunctor) = struct + let lambda : ('a, 'a) P.p -> ('a -> 'b) -> ('a, 'b) P.p = + fun paa f -> P.dimap id f paa + ;; + + let rho : ('b, 'b) P.p -> ('a -> 'b) -> ('a, 'b) P.p = + fun pbb f -> P.dimap f id pbb + ;; +end diff --git a/src/content/3.10/code/ocaml/snippet10.ml b/src/content/3.10/code/ocaml/snippet10.ml new file mode 100644 index 00000000..e4c5bd38 --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet10.ml @@ -0,0 +1,4 @@ +module type ProdP = sig + type ('a, 'b) p + type ('a, 'b) prod_p = ('a -> 'b) -> ('a, 'b) p +end diff --git a/src/content/3.10/code/ocaml/snippet11.ml b/src/content/3.10/code/ocaml/snippet11.ml new file mode 100644 index 00000000..a4571b9f --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet11.ml @@ -0,0 +1,4 @@ +module type DiaProd = sig + type ('a, 'b) p + type 'a diaprod = DiaProd of ('a, 'a) p +end diff --git a/src/content/3.10/code/ocaml/snippet12.ml b/src/content/3.10/code/ocaml/snippet12.ml new file mode 100644 index 00000000..e5386ec0 --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet12.ml @@ -0,0 +1,15 @@ +module EndsWithDiaProd + (P : Profunctor) + (D : DiaProd with type ('a, 'b) p = ('a, 'b) P.p) + (PP : ProdP with type ('a, 'b) p = ('a, 'b) P.p) = +struct + module E = EndsEqualizer (P) + + let lambdaP : 'a D.diaprod -> ('a, 'b) PP.prod_p = + fun (DiaProd paa) -> E.lambda paa + ;; + + let rhoP : 'b D.diaprod -> ('a, 'b) PP.prod_p = + fun (DiaProd pbb) -> E.rho pbb + ;; +end diff --git a/src/content/3.10/code/ocaml/snippet13.ml b/src/content/3.10/code/ocaml/snippet13.ml new file mode 100644 index 00000000..16b64c0f --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet13.ml @@ -0,0 +1,4 @@ +(* Higher rank types can be introduced via records *) +module NT_as_Ends (F : Functor) (G : Functor) = struct + type set_of_nt = { nt : 'a. 'a F.t -> 'a G.t } +end diff --git a/src/content/3.10/code/ocaml/snippet14.ml b/src/content/3.10/code/ocaml/snippet14.ml new file mode 100644 index 00000000..2424ce89 --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet14.ml @@ -0,0 +1,3 @@ +module Coend (P : Profunctor) = struct + type coend = Coend of { c : 'a. ('a, 'a) P.p } +end diff --git a/src/content/3.10/code/ocaml/snippet15.ml b/src/content/3.10/code/ocaml/snippet15.ml new file mode 100644 index 00000000..f1196100 --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet15.ml @@ -0,0 +1,8 @@ +module type SumP = sig + type a + type b + type ('a, 'b) p + + val f : b -> a + val pab : (a, b) p +end diff --git a/src/content/3.10/code/ocaml/snippet16.ml b/src/content/3.10/code/ocaml/snippet16.ml new file mode 100644 index 00000000..f482800b --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet16.ml @@ -0,0 +1,35 @@ +module type DiagSum = sig + type a + type ('a, 'b) p + + val paa : (a, a) p +end + +module CoEndImpl (P : Profunctor) = struct + type a + type b + + module type Sum_P = + SumP + with type ('a, 'b) p = ('a, 'b) P.p + and type a = a + and type b = b + + let lambda (module S : Sum_P) = + (module struct + type a = S.b + type ('a, 'b) p = ('a, 'b) P.p + + let paa = P.dimap S.f id S.pab + end : DiagSum) + ;; + + let rho (module S : Sum_P) = + (module struct + type a = S.a + type ('a, 'b) p = ('a, 'b) P.p + + let paa = P.dimap id S.f S.pab + end : DiagSum) + ;; +end diff --git a/src/content/3.10/code/ocaml/snippet17.ml b/src/content/3.10/code/ocaml/snippet17.ml new file mode 100644 index 00000000..9fddf713 --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet17.ml @@ -0,0 +1,6 @@ +module type DiagSum = sig + type a + type ('a, 'b) p + + val paa : (a, a) p +end diff --git a/src/content/3.10/code/ocaml/snippet18.ml b/src/content/3.10/code/ocaml/snippet18.ml new file mode 100644 index 00000000..b69305ad --- /dev/null +++ b/src/content/3.10/code/ocaml/snippet18.ml @@ -0,0 +1,7 @@ +module type Procompose = sig + type ('a, 'b) p + type ('a, 'b) q + + type (_, _) procompose = + | Procompose : (('a, 'c) q -> ('c, 'b) p) -> ('a, 'b) procompose +end diff --git a/src/content/3.11/code/ocaml/snippet01.ml b/src/content/3.11/code/ocaml/snippet01.ml new file mode 100644 index 00000000..d83c38c4 --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet01.ml @@ -0,0 +1,5 @@ +module type Ran = sig + type 'a k + type 'a d + type 'a ran = Ran of { r : 'i. ('a -> 'i k) -> 'i d } +end diff --git a/src/content/3.11/code/ocaml/snippet02.ml b/src/content/3.11/code/ocaml/snippet02.ml new file mode 100644 index 00000000..14fbd57a --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +val f : string -> int tree diff --git a/src/content/3.11/code/ocaml/snippet03.ml b/src/content/3.11/code/ocaml/snippet03.ml new file mode 100644 index 00000000..be1c8f93 --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet03.ml @@ -0,0 +1,2 @@ +(* Higher rank polymorphic functions can be achieved using records *) +{ r : 'i. (a -> 'i k) -> 'i } diff --git a/src/content/3.11/code/ocaml/snippet04.ml b/src/content/3.11/code/ocaml/snippet04.ml new file mode 100644 index 00000000..e9eb201b --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet04.ml @@ -0,0 +1,10 @@ +module type Lst = sig + type a + type m + + module M : Monoid with type m = m + + type lst = (a -> M.m) -> M.m + + val f : lst +end diff --git a/src/content/3.11/code/ocaml/snippet05.ml b/src/content/3.11/code/ocaml/snippet05.ml new file mode 100644 index 00000000..9e55f9cc --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet05.ml @@ -0,0 +1,29 @@ +let fold_map (type i) (module M : Monoid with type m = i) xs f = + List.fold_left (fun acc a -> M.mappend acc (f a)) M.mempty xs +;; + +let to_lst (type x) (xs : x list) = + let module LM : Monoid with type m = x list = + ListMonoid (struct + type a = x + end) + in + (module struct + type a = x + type m = x list + + module M = LM + + type lst = (a -> LM.m) -> LM.m + + let f g = fold_map (module LM) xs g + end : Lst + with type a = x) +;; + +let from_lst + (type x) + (module LstImpl : Lst with type a = x and type m = x list) + = + LstImpl.f (fun x -> [ x ]) +;; diff --git a/src/content/3.11/code/ocaml/snippet06.ml b/src/content/3.11/code/ocaml/snippet06.ml new file mode 100644 index 00000000..2b287493 --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet06.ml @@ -0,0 +1,9 @@ +module type Lan = sig + type 'a k + type 'a d + type a + type i + + val fk : i k -> a + val di : i d +end diff --git a/src/content/3.11/code/ocaml/snippet07.ml b/src/content/3.11/code/ocaml/snippet07.ml new file mode 100644 index 00000000..2ce0bb5c --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet07.ml @@ -0,0 +1,9 @@ +module type Exp = sig + type a + type b + type 'a d = I of 'a + type 'a k = 'a * a + + include + Lan with type 'a k := a * 'a and type 'a d := 'a d and type a := b +end diff --git a/src/content/3.11/code/ocaml/snippet08.ml b/src/content/3.11/code/ocaml/snippet08.ml new file mode 100644 index 00000000..c3439edc --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet08.ml @@ -0,0 +1,23 @@ +let to_exp (type a' b') f = + (module struct + type a = a' + type b = b' + type 'a d = I of 'a + type 'a k = 'a * a + type i = unit + + let fk (a, _) = f a + let di = I () + end : Exp + with type a = a' + and type b = b') +;; + +let from_exp + (type a' b') + (module E : Exp with type a = a' and type b = b') + a + = + let (I i) = E.di in + E.fk (a, i) +;; diff --git a/src/content/3.11/code/ocaml/snippet09.ml b/src/content/3.11/code/ocaml/snippet09.ml new file mode 100644 index 00000000..85502e96 --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet09.ml @@ -0,0 +1,8 @@ +module type FreeF = sig + type 'a f + type a + type i + + val h : i -> a + val fi : i -> i f +end diff --git a/src/content/3.11/code/ocaml/snippet10.ml b/src/content/3.11/code/ocaml/snippet10.ml new file mode 100644 index 00000000..32fd08b4 --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet10.ml @@ -0,0 +1,23 @@ +module FreeFunctor (F : sig + type 'a f +end) : Functor = struct + module type F = FreeF with type 'a f = 'a F.f + + type 'a t = (module F with type a = 'a) + + let fmap + (type a' b') + (f : a' -> b') + (module FF : F with type a = a') + = + (module struct + type 'a f = 'a F.f + type a = b' + type i = FF.i + + let h i = f (FF.h i) + let fi = FF.fi + end : F + with type a = b') + ;; +end diff --git a/src/content/3.11/code/ocaml/snippet11.ml b/src/content/3.11/code/ocaml/snippet11.ml new file mode 100644 index 00000000..c4863454 --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet11.ml @@ -0,0 +1,6 @@ +module type FreeF_Alt = sig + type a + type 'a f + + val freeF : (a -> 'i) -> 'i f +end diff --git a/src/content/3.11/code/ocaml/snippet12.ml b/src/content/3.11/code/ocaml/snippet12.ml new file mode 100644 index 00000000..d701bc15 --- /dev/null +++ b/src/content/3.11/code/ocaml/snippet12.ml @@ -0,0 +1,17 @@ +module FreeFunctorAlt (F : sig + type 'a f +end) : Functor = struct + module type F = FreeF_Alt with type 'a f = 'a F.f + + type 'a t = (module F with type a = 'a) + + let fmap (type a' b') f (module FF : F with type a = a') = + (module struct + type a = b' + type 'a f = 'a F.f + + let freeF bi = FF.freeF (fun a -> bi (f a)) + end : F + with type a = b') + ;; +end diff --git a/src/content/3.14/code/ocaml/snippet01.ml b/src/content/3.14/code/ocaml/snippet01.ml new file mode 100644 index 00000000..4e78157b --- /dev/null +++ b/src/content/3.14/code/ocaml/snippet01.ml @@ -0,0 +1,5 @@ +type ('a, 'b) either = + | Left of 'a + | Right of 'b + +type two = (unit, unit) either diff --git a/src/content/3.14/code/ocaml/snippet02.ml b/src/content/3.14/code/ocaml/snippet02.ml new file mode 100644 index 00000000..39bc267c --- /dev/null +++ b/src/content/3.14/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +val raise : unit -> 'a diff --git a/src/content/3.14/code/ocaml/snippet03.ml b/src/content/3.14/code/ocaml/snippet03.ml new file mode 100644 index 00000000..aee7e188 --- /dev/null +++ b/src/content/3.14/code/ocaml/snippet03.ml @@ -0,0 +1 @@ +type 'a option = (unit, 'a) either diff --git a/src/content/3.14/code/ocaml/snippet04.ml b/src/content/3.14/code/ocaml/snippet04.ml new file mode 100644 index 00000000..e30a56a0 --- /dev/null +++ b/src/content/3.14/code/ocaml/snippet04.ml @@ -0,0 +1,3 @@ +type 'a option = + | None + | Some of 'a diff --git a/src/content/3.2/code/ocaml/snippet01.ml b/src/content/3.2/code/ocaml/snippet01.ml new file mode 100644 index 00000000..fd327462 --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +let swap (a, b) = b, a diff --git a/src/content/3.2/code/ocaml/snippet02.ml b/src/content/3.2/code/ocaml/snippet02.ml new file mode 100644 index 00000000..00450ef3 --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet02.ml @@ -0,0 +1,5 @@ +module type Unit_Example = sig + type 'a m + + val return : 'd -> 'd m +end diff --git a/src/content/3.2/code/ocaml/snippet03.ml b/src/content/3.2/code/ocaml/snippet03.ml new file mode 100644 index 00000000..a2991878 --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet03.ml @@ -0,0 +1,5 @@ +module type Counit_Example = sig + type 'c w + + val extract : 'c w -> 'c +end diff --git a/src/content/3.2/code/ocaml/snippet04.ml b/src/content/3.2/code/ocaml/snippet04.ml new file mode 100644 index 00000000..3e9e13ad --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet04.ml @@ -0,0 +1,8 @@ +(* L is Functor F and R is Representable Functor U *) +module type Adjunction = functor + (F : Functor) + (U : Representable) + -> sig + val unit : 'a -> 'a F.t U.t + val counit : 'a U.t F.t -> 'a +end diff --git a/src/content/3.2/code/ocaml/snippet05.ml b/src/content/3.2/code/ocaml/snippet05.ml new file mode 100644 index 00000000..d4d7c604 --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet05.ml @@ -0,0 +1,7 @@ +module type Adjunction_HomSet = functor + (F : Functor) + (U : Representable) + -> sig + val left_adjunct : ('a F.t -> 'b) -> 'a -> 'b U.t + val right_adjunct : ('a -> 'b U.t) -> 'a F.t -> 'b +end diff --git a/src/content/3.2/code/ocaml/snippet06.ml b/src/content/3.2/code/ocaml/snippet06.ml new file mode 100644 index 00000000..818c149b --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet06.ml @@ -0,0 +1,66 @@ +(* Putting it all together to show the equivalence between unit/counit and left_adjunct/right_adjunct *) +module type Adjunction = functor + (F : Functor) + (U : Representable) + -> sig + val unit : 'a -> 'a F.t U.t + val counit : 'a U.t F.t -> 'a + val left_adjunct : ('a F.t -> 'b) -> 'a -> 'b U.t + val right_adjunct : ('a -> 'b U.t) -> 'a F.t -> 'b +end + +(* Adjunction via unit/counit *) +module type Adjunction_Unit_Counit = functor + (F : Functor) + (U : Representable) + -> sig + val unit : 'a -> 'a F.t U.t + val counit : 'a U.t F.t -> 'a +end + +(* Adjunction via left and right adjoints *) +module type Adjunction_Hom_Set = functor + (F : Functor) + (U : Representable) + -> sig + val left_adjunct : ('a F.t -> 'b) -> 'a -> 'b U.t + val right_adjunct : ('a -> 'b U.t) -> 'a F.t -> 'b +end + +(* Implementing unit/counit from left and right adjoint definitions *) +module Adjunction_From_Hom_Set (A : Adjunction_Hom_Set) : Adjunction = +functor + (F : Functor) + (U : Representable) + -> + struct + type 't f = 't F.t + type 't u = 't U.t + + module M = A (F) (U) + include M + + let unit : 'a. 'a -> 'a f u = fun a -> M.left_adjunct idty a + + let counit : 'a. 'a u f -> 'a = + fun fua -> M.right_adjunct idty fua + ;; + end + +(* Implementing left and right adjunct from unit/counit Definitions *) +module Adjunction_From_Unit_Counit (A : Adjunction_Unit_Counit) : + Adjunction = +functor + (F : Functor) + (U : Representable) + -> + struct + type 't f = 't F.t + type 't u = 't U.t + + module M = A (F) (U) + include M + + let left_adjunct f a = (U.fmap f) (M.unit a) + let right_adjunct f fa = M.counit (F.fmap f fa) + end diff --git a/src/content/3.2/code/ocaml/snippet07.ml b/src/content/3.2/code/ocaml/snippet07.ml new file mode 100644 index 00000000..d746ba3e --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +let factorizer p q x = p x, q x diff --git a/src/content/3.2/code/ocaml/snippet08.ml b/src/content/3.2/code/ocaml/snippet08.ml new file mode 100644 index 00000000..e09ff802 --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet08.ml @@ -0,0 +1,2 @@ +compose fst (factorizer p q) = p +compose snd (factorizer p q) = q diff --git a/src/content/3.2/code/ocaml/snippet09.ml b/src/content/3.2/code/ocaml/snippet09.ml new file mode 100644 index 00000000..230e69b5 --- /dev/null +++ b/src/content/3.2/code/ocaml/snippet09.ml @@ -0,0 +1 @@ +int * bool ~ (int, bool) diff --git a/src/content/3.3/code/ocaml/snippet01.ml b/src/content/3.3/code/ocaml/snippet01.ml new file mode 100644 index 00000000..2e2f4e12 --- /dev/null +++ b/src/content/3.3/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +type string = char list diff --git a/src/content/3.3/code/ocaml/snippet02.ml b/src/content/3.3/code/ocaml/snippet02.ml new file mode 100644 index 00000000..048eddf7 --- /dev/null +++ b/src/content/3.3/code/ocaml/snippet02.ml @@ -0,0 +1,2 @@ +let to_nat : unit list -> int = List.length +let to_lst : int -> unit list = fun n -> List.init n ~f:(fun _ -> ()) diff --git a/src/content/3.4/code/ocaml/snippet01.ml b/src/content/3.4/code/ocaml/snippet01.ml new file mode 100644 index 00000000..7b7947a1 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet01.ml @@ -0,0 +1,12 @@ +(* Depends on OCaml library Core *) +module Vlen (F : Functor with type 'a t = 'a list) = struct + let summable = + (module Float : Base__.Container_intf.Summable + with type t = float) + + + let vlen = + Float.sqrt + <.> List.sum summable ~f:Fn.id + <.> F.fmap (flip Float.int_pow 2) +end diff --git a/src/content/3.4/code/ocaml/snippet02.ml b/src/content/3.4/code/ocaml/snippet02.ml new file mode 100644 index 00000000..b7f71134 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet02.ml @@ -0,0 +1,7 @@ +module WriterInstance (W : sig + type w +end) : Functor with type 'a t = (W.w, 'a) writer = struct + type 'a t = (W.w, 'a) writer + + let fmap f (Writer (a, w)) = Writer (f a, w) +end diff --git a/src/content/3.4/code/ocaml/snippet03.ml b/src/content/3.4/code/ocaml/snippet03.ml new file mode 100644 index 00000000..26434fbb --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet03.ml @@ -0,0 +1 @@ +'a -> ('w, 'b) writer diff --git a/src/content/3.4/code/ocaml/snippet04.ml b/src/content/3.4/code/ocaml/snippet04.ml new file mode 100644 index 00000000..82df8ae9 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet04.ml @@ -0,0 +1,6 @@ +module type Monad = sig + type 'a m + + val ( >=> ) : ('a -> 'b m) -> ('b -> 'c m) -> 'a -> 'c m + val return : 'a -> 'a m +end diff --git a/src/content/3.4/code/ocaml/snippet05.ml b/src/content/3.4/code/ocaml/snippet05.ml new file mode 100644 index 00000000..29e2c98a --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet05.ml @@ -0,0 +1,12 @@ +module WriterMonad (W : Monoid) : + Monad with type 'a m = (W.a, 'a) writer = struct + type 'a m = (W.a, 'a) writer + + let ( >=> ) f g a = + let (Writer (b, w)) = f a in + let (Writer (c, w')) = g b in + Writer (c, W.mappend w w') + + + let return a = Writer (a, W.mempty) +end diff --git a/src/content/3.4/code/ocaml/snippet06.ml b/src/content/3.4/code/ocaml/snippet06.ml new file mode 100644 index 00000000..5753e0f3 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +let tell w = Writer ((), w) diff --git a/src/content/3.4/code/ocaml/snippet07.ml b/src/content/3.4/code/ocaml/snippet07.ml new file mode 100644 index 00000000..41add86e --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +let (>=>) f g = fun a -> ... diff --git a/src/content/3.4/code/ocaml/snippet08.ml b/src/content/3.4/code/ocaml/snippet08.ml new file mode 100644 index 00000000..e58dcba1 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet08.ml @@ -0,0 +1,3 @@ +let (>=>) f g = fun a -> + let mb = f a in + ... diff --git a/src/content/3.4/code/ocaml/snippet09.ml b/src/content/3.4/code/ocaml/snippet09.ml new file mode 100644 index 00000000..2ffe0285 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet09.ml @@ -0,0 +1 @@ +val ( >>= ) : 'a m -> ('a -> 'b m) -> 'b m diff --git a/src/content/3.4/code/ocaml/snippet10.ml b/src/content/3.4/code/ocaml/snippet10.ml new file mode 100644 index 00000000..6c4bbee4 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet10.ml @@ -0,0 +1,6 @@ +module type Monad_Bind = sig + type 'a m + + val ( >>= ) : 'a m -> ('a -> 'b m) -> 'b m + val return : 'a -> 'a m +end diff --git a/src/content/3.4/code/ocaml/snippet11.ml b/src/content/3.4/code/ocaml/snippet11.ml new file mode 100644 index 00000000..299aba9e --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet11.ml @@ -0,0 +1,5 @@ +module WriterMonadBind (W : Monoid) = struct + let ( >>= ) (Writer (a, w)) f = + let (Writer (b, w')) = f a in + Writer (b, W.mappend w w') +end diff --git a/src/content/3.4/code/ocaml/snippet12.ml b/src/content/3.4/code/ocaml/snippet12.ml new file mode 100644 index 00000000..1c2d7917 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet12.ml @@ -0,0 +1 @@ +val join : ('a m) m : 'a m diff --git a/src/content/3.4/code/ocaml/snippet13.ml b/src/content/3.4/code/ocaml/snippet13.ml new file mode 100644 index 00000000..a3ce5d8c --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet13.ml @@ -0,0 +1,9 @@ +module BindUsingFunctionAndJoin (F : Functor) = struct + type 'a m = 'a F.t + + external join : 'a m m -> 'a m = "%identity" + (** Make the type signature of join work + without providing an implementation **) + + let ( >>= ) ma f = join (F.fmap f ma) +end diff --git a/src/content/3.4/code/ocaml/snippet14.ml b/src/content/3.4/code/ocaml/snippet14.ml new file mode 100644 index 00000000..ea2c5104 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet14.ml @@ -0,0 +1,6 @@ +module type Monad_Join = functor (F : Functor) -> sig + type 'a m = 'a F.t + + val join : 'a m m -> 'a m + val return : 'a -> 'a m +end diff --git a/src/content/3.4/code/ocaml/snippet15.ml b/src/content/3.4/code/ocaml/snippet15.ml new file mode 100644 index 00000000..7693b749 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet15.ml @@ -0,0 +1,3 @@ +module Fmap_Using_Monad (M : Monad_Bind) = struct + let fmap f ma = M.( >>= ) ma (fun a -> M.return (f a)) +end diff --git a/src/content/3.4/code/ocaml/snippet16.ml b/src/content/3.4/code/ocaml/snippet16.ml new file mode 100644 index 00000000..1d9f414c --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet16.ml @@ -0,0 +1,3 @@ +module Writer_Join (W : Monoid) = struct + let join (Writer (Writer (a, w'), w)) = Writer (a, W.mappend w w') +end diff --git a/src/content/3.4/code/ocaml/snippet17.ml b/src/content/3.4/code/ocaml/snippet17.ml new file mode 100644 index 00000000..8c73d56f --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet17.ml @@ -0,0 +1,7 @@ +(* Import Str module using this - #require "str" *) +let to_words s = Writer (Str.split (Str.regexp "\b") s, "to_words") + +module Writer_Process (W : Monad with type 'a m = (string, 'a) writer) = +struct + let process = W.(up_case >=> to_words) +end diff --git a/src/content/3.4/code/ocaml/snippet18.ml b/src/content/3.4/code/ocaml/snippet18.ml new file mode 100644 index 00000000..f8456604 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet18.ml @@ -0,0 +1,10 @@ +module Process_Do + (W : Monad_Bind with type 'a m = (string, 'a) writer) = +struct + (* Needs OCaml compiler >= 4.08 *) + let ( let* ) = W.( >>= ) + + let process s = + let* up_str = up_case s in + to_words up_str +end diff --git a/src/content/3.4/code/ocaml/snippet19.ml b/src/content/3.4/code/ocaml/snippet19.ml new file mode 100644 index 00000000..1003c925 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet19.ml @@ -0,0 +1 @@ +let up_case s = Writer (String.uppercase s, "up_case ") diff --git a/src/content/3.4/code/ocaml/snippet20.ml b/src/content/3.4/code/ocaml/snippet20.ml new file mode 100644 index 00000000..b1a90548 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet20.ml @@ -0,0 +1,5 @@ +module Process_Bind_Without_Do + (W : Monad_Bind with type 'a m = (string, 'a) writer) = +struct + let process s = W.(up_case s >>= fun up_str -> to_words up_str) +end diff --git a/src/content/3.4/code/ocaml/snippet21.ml b/src/content/3.4/code/ocaml/snippet21.ml new file mode 100644 index 00000000..21ea3a73 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet21.ml @@ -0,0 +1 @@ +let* up_str <- up_case s diff --git a/src/content/3.4/code/ocaml/snippet22.ml b/src/content/3.4/code/ocaml/snippet22.ml new file mode 100644 index 00000000..f53217ca --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet22.ml @@ -0,0 +1,12 @@ +module Process_Tell + (W : Monad_Bind with type 'a m = (string, 'a) writer) = +struct + (* Needs OCaml compiler >= 4.08 *) + let ( let* ) = W.( >>= ) + let tell w = Writer ((), w) + + let process s = + let* up_str = up_case s in + let* _ = tell "to_words " in + to_words up_str +end diff --git a/src/content/3.4/code/ocaml/snippet23.ml b/src/content/3.4/code/ocaml/snippet23.ml new file mode 100644 index 00000000..88de8d41 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet23.ml @@ -0,0 +1,10 @@ +module Process_Bind_Without_Do + (W : Monad_Bind with type 'a m = (string, 'a) writer) = +struct + let tell w = Writer ((), w) + + let process s = + W.( + up_case s + >>= fun up_str -> tell "to_words" >>= fun _ -> to_words up_str) +end diff --git a/src/content/3.4/code/ocaml/snippet24.ml b/src/content/3.4/code/ocaml/snippet24.ml new file mode 100644 index 00000000..9e597b4f --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet24.ml @@ -0,0 +1,3 @@ +module Monad_Ops (M : Monad_Bind) = struct + let ( >> ) m k = M.(m >>= fun _ -> k) +end diff --git a/src/content/3.4/code/ocaml/snippet25.ml b/src/content/3.4/code/ocaml/snippet25.ml new file mode 100644 index 00000000..708a9224 --- /dev/null +++ b/src/content/3.4/code/ocaml/snippet25.ml @@ -0,0 +1,11 @@ +module Process_Bind_Without_Do + (W : Monad_Bind with type 'a m = (string, 'a) writer) = +struct + open Monad_Ops (W) + + let tell w = Writer ((), w) + + let process s = + W.( + up_case s >>= fun up_str -> tell "to_words" >> to_words up_str) +end diff --git a/src/content/3.5/code/ocaml/snippet01.ml b/src/content/3.5/code/ocaml/snippet01.ml new file mode 100644 index 00000000..4690b6f1 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet01.ml @@ -0,0 +1,6 @@ +module List_Monad : Monad_Join = struct + type 'a m = 'a list + + let join = List.concat + let return a = [ a ] +end diff --git a/src/content/3.5/code/ocaml/snippet02.ml b/src/content/3.5/code/ocaml/snippet02.ml new file mode 100644 index 00000000..0220b751 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +let ( >>= ) xs k = List.concat (List.map k xs) diff --git a/src/content/3.5/code/ocaml/snippet03.ml b/src/content/3.5/code/ocaml/snippet03.ml new file mode 100644 index 00000000..8245c2d0 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet03.ml @@ -0,0 +1,12 @@ +module Pythagorean = struct + let ( let* ) = Fn.flip Gen.flat_map + let ( let+ ) x f = Gen.map f x + let guard b = if b then Gen.return () else Gen.empty + + let triples = + let* z = Gen.init (fun i -> i + 1) in + let* x = Gen.init ~limit:z (fun i -> i + 1) in + let* y = Gen.init ~limit:z (fun i -> i + x) in + let+ _ = guard ((x * x) + (y * y) = z * z) in + Gen.return (x, y, z) +end diff --git a/src/content/3.5/code/ocaml/snippet04.ml b/src/content/3.5/code/ocaml/snippet04.ml new file mode 100644 index 00000000..c1e5237e --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet04.ml @@ -0,0 +1,3 @@ +let guard = function + | true -> [ () ] + | false -> [] diff --git a/src/content/3.5/code/ocaml/snippet05.ml b/src/content/3.5/code/ocaml/snippet05.ml new file mode 100644 index 00000000..c02c2d05 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet05.ml @@ -0,0 +1,13 @@ +module Pythagorean = struct + let ( let* ) = Fn.flip Gen.flat_map + let ( let+ ) x f = Gen.map f x + let guard b = if b then Gen.return () else Gen.empty + + let triples = + let* z = Gen.init (fun i -> i + 1) in + let* x = Gen.init ~limit:z (fun i -> i + 1) in + let* y = Gen.init ~limit:z (fun i -> i + x) in + if (x * x) + (y * y) = z * z + then Gen.return (x, y, z) + else Gen.empty +end diff --git a/src/content/3.5/code/ocaml/snippet06.ml b/src/content/3.5/code/ocaml/snippet06.ml new file mode 100644 index 00000000..1aa05bd8 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +type ('e, 'a) reader = Reader of ('e -> 'a) diff --git a/src/content/3.5/code/ocaml/snippet07.ml b/src/content/3.5/code/ocaml/snippet07.ml new file mode 100644 index 00000000..244db7be --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +let run_reader (Reader f) e = f e diff --git a/src/content/3.5/code/ocaml/snippet08.ml b/src/content/3.5/code/ocaml/snippet08.ml new file mode 100644 index 00000000..0331adeb --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +let (>>=) ra k = Reader (fun e -> ...) diff --git a/src/content/3.5/code/ocaml/snippet09.ml b/src/content/3.5/code/ocaml/snippet09.ml new file mode 100644 index 00000000..90b73510 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet09.ml @@ -0,0 +1,3 @@ +let (>>=) ra k = Reader (fun e -> + let a = run_reader ra e in + ...) diff --git a/src/content/3.5/code/ocaml/snippet10.ml b/src/content/3.5/code/ocaml/snippet10.ml new file mode 100644 index 00000000..76e75c22 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet10.ml @@ -0,0 +1,4 @@ +let (>>=) ra k = Reader (fun e -> + let a = run_reader ra e in + let rb = k a in + ...) diff --git a/src/content/3.5/code/ocaml/snippet11.ml b/src/content/3.5/code/ocaml/snippet11.ml new file mode 100644 index 00000000..2ca80370 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet11.ml @@ -0,0 +1,6 @@ +let ( >>= ) ra k = + Reader + (fun e -> + let a = run_reader ra e in + let rb = k a in + run_reader rb e) diff --git a/src/content/3.5/code/ocaml/snippet12.ml b/src/content/3.5/code/ocaml/snippet12.ml new file mode 100644 index 00000000..4d9836cf --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet12.ml @@ -0,0 +1,10 @@ +module ReaderMonad (T : sig + type t +end) : Monad_Bind = struct + type 'a m = (T.t, 'a) reader + + let return a = Reader (fun e -> a) + + let ( >>= ) ra k = + Reader (fun e -> run_reader (k (run_reader ra e)) e) +end diff --git a/src/content/3.5/code/ocaml/snippet13.ml b/src/content/3.5/code/ocaml/snippet13.ml new file mode 100644 index 00000000..4b8033fd --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet13.ml @@ -0,0 +1 @@ +type ('w, 'a) writer = Writer of ('a * 'w) diff --git a/src/content/3.5/code/ocaml/snippet14.ml b/src/content/3.5/code/ocaml/snippet14.ml new file mode 100644 index 00000000..e58a8d0e --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet14.ml @@ -0,0 +1 @@ +let run_writer (Writer (a, w)) = a, w diff --git a/src/content/3.5/code/ocaml/snippet15.ml b/src/content/3.5/code/ocaml/snippet15.ml new file mode 100644 index 00000000..61eaacd4 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet15.ml @@ -0,0 +1,9 @@ +module WriterMonad (W : Monoid) : Monad_Bind = struct + type 'a m = (W.t, 'a) writer + + let return a = Writer (a, W.mempty) + + let ( >>= ) (Writer (a, w)) k = + let a', w' = run_writer (k a) in + Writer (a', W.mappend w w') +end diff --git a/src/content/3.5/code/ocaml/snippet16.ml b/src/content/3.5/code/ocaml/snippet16.ml new file mode 100644 index 00000000..7a68373c --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet16.ml @@ -0,0 +1 @@ +type ('s, 'a) state = State of ('s -> 'a * 's) diff --git a/src/content/3.5/code/ocaml/snippet17.ml b/src/content/3.5/code/ocaml/snippet17.ml new file mode 100644 index 00000000..b839b174 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet17.ml @@ -0,0 +1 @@ +let run_state (State f) s = f s diff --git a/src/content/3.5/code/ocaml/snippet18.ml b/src/content/3.5/code/ocaml/snippet18.ml new file mode 100644 index 00000000..9a23fe8a --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet18.ml @@ -0,0 +1,6 @@ +let ( >>= ) sa k = + State + (fun s -> + let a, s' = run_state sa s in + let sb = k a in + run_state sb s') diff --git a/src/content/3.5/code/ocaml/snippet19.ml b/src/content/3.5/code/ocaml/snippet19.ml new file mode 100644 index 00000000..94e7168e --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet19.ml @@ -0,0 +1,15 @@ +module State_Monad (S : sig + type t +end) : Monad_Bind = struct + type 'a m = (S.t, 'a) state + + let ( >>= ) sa k = + State + (fun s -> + let a, s' = run_state sa s in + let sb = k a in + run_state sb s') + + + let return a = State (fun s -> a, s) +end diff --git a/src/content/3.5/code/ocaml/snippet20.ml b/src/content/3.5/code/ocaml/snippet20.ml new file mode 100644 index 00000000..bfe543f5 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet20.ml @@ -0,0 +1 @@ +let get = State (fun s -> s, s) diff --git a/src/content/3.5/code/ocaml/snippet21.ml b/src/content/3.5/code/ocaml/snippet21.ml new file mode 100644 index 00000000..4df00fd9 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet21.ml @@ -0,0 +1 @@ +let put s' = State (fun s -> (), s') diff --git a/src/content/3.5/code/ocaml/snippet22.ml b/src/content/3.5/code/ocaml/snippet22.ml new file mode 100644 index 00000000..a1f11917 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet22.ml @@ -0,0 +1,10 @@ +module OptionMonad : Monad_Bind = struct + type 'a m = 'a option + + let ( >>= ) = function + | Some a -> fun k -> k a + | None -> fun _ -> None + + + let return a = Some a +end diff --git a/src/content/3.5/code/ocaml/snippet23.ml b/src/content/3.5/code/ocaml/snippet23.ml new file mode 100644 index 00000000..fadbbecd --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet23.ml @@ -0,0 +1 @@ +type ('r, 'a) cont = Cont of (('a -> 'r) -> 'r) diff --git a/src/content/3.5/code/ocaml/snippet24.ml b/src/content/3.5/code/ocaml/snippet24.ml new file mode 100644 index 00000000..090a346f --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet24.ml @@ -0,0 +1 @@ +let run_cont (Cont k) h = k h diff --git a/src/content/3.5/code/ocaml/snippet25.ml b/src/content/3.5/code/ocaml/snippet25.ml new file mode 100644 index 00000000..7f42143a --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet25.ml @@ -0,0 +1,5 @@ +val ( >>= ) + : (('a -> 'r) -> 'r) + -> ('a -> ('b -> 'r) -> 'r) + -> ('b -> 'r) + -> 'r diff --git a/src/content/3.5/code/ocaml/snippet26.ml b/src/content/3.5/code/ocaml/snippet26.ml new file mode 100644 index 00000000..c788056a --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet26.ml @@ -0,0 +1 @@ +let (>>=) ka kab = Cont (fun hb -> ...) diff --git a/src/content/3.5/code/ocaml/snippet27.ml b/src/content/3.5/code/ocaml/snippet27.ml new file mode 100644 index 00000000..accb4800 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet27.ml @@ -0,0 +1 @@ +run_cont ka (fun a -> ...) diff --git a/src/content/3.5/code/ocaml/snippet28.ml b/src/content/3.5/code/ocaml/snippet28.ml new file mode 100644 index 00000000..2532b0ef --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet28.ml @@ -0,0 +1,4 @@ +;; +run_cont ka (fun a -> + let kb = kab a in + run_cont kb hb) diff --git a/src/content/3.5/code/ocaml/snippet29.ml b/src/content/3.5/code/ocaml/snippet29.ml new file mode 100644 index 00000000..cb0e9280 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet29.ml @@ -0,0 +1,10 @@ +module Cont_Monad (R : sig + type t +end) : Monad_Bind = struct + type 'a m = (R.t, 'a) cont + + let return a = Cont (fun ha -> ha a) + + let ( >>= ) ka kab = + Cont (fun hb -> run_cont ka (fun a -> run_cont (kab a) hb)) +end diff --git a/src/content/3.5/code/ocaml/snippet30.ml b/src/content/3.5/code/ocaml/snippet30.ml new file mode 100644 index 00000000..dd564e41 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet30.ml @@ -0,0 +1,6 @@ +module type Terminal_IO = sig + (* OCaml doesn't have a built-in IO type*) + type 'a io = IO of (unit -> 'a) + + val get_char : unit -> char io +end diff --git a/src/content/3.5/code/ocaml/snippet31.ml b/src/content/3.5/code/ocaml/snippet31.ml new file mode 100644 index 00000000..4b9fafd6 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet31.ml @@ -0,0 +1 @@ +val main : unit io diff --git a/src/content/3.5/code/ocaml/snippet32.ml b/src/content/3.5/code/ocaml/snippet32.ml new file mode 100644 index 00000000..fa86681a --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet32.ml @@ -0,0 +1 @@ +val main : unit -> unit io diff --git a/src/content/3.5/code/ocaml/snippet33.ml b/src/content/3.5/code/ocaml/snippet33.ml new file mode 100644 index 00000000..733a4912 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet33.ml @@ -0,0 +1 @@ +type 'a io = realworld -> 'a * realworld diff --git a/src/content/3.5/code/ocaml/snippet34.ml b/src/content/3.5/code/ocaml/snippet34.ml new file mode 100644 index 00000000..ef1a0cbe --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet34.ml @@ -0,0 +1 @@ +type 'a io = realworld state diff --git a/src/content/3.5/code/ocaml/snippet35.ml b/src/content/3.5/code/ocaml/snippet35.ml new file mode 100644 index 00000000..6eb10572 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet35.ml @@ -0,0 +1 @@ +val put_str : string -> unit io diff --git a/src/content/3.5/code/ocaml/snippet36.ml b/src/content/3.5/code/ocaml/snippet36.ml new file mode 100644 index 00000000..44a24bd9 --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet36.ml @@ -0,0 +1 @@ +val put_str : string -> unit diff --git a/src/content/3.5/code/ocaml/snippet37.ml b/src/content/3.5/code/ocaml/snippet37.ml new file mode 100644 index 00000000..2e27ec6f --- /dev/null +++ b/src/content/3.5/code/ocaml/snippet37.ml @@ -0,0 +1,22 @@ +(* Monad implementation for type io *) +module IOMonad : Monad_Bind with type 'a m = 'a io = struct + type 'a m = 'a io + + let return x = IO (fun () -> x) + + let ( >>= ) m f = + IO + (fun () -> + let (IO m') = m in + let (IO m'') = f (m' ()) in + m'' ()) +end + +(* main *) +module IO_Main = struct + let ( let* ) = IOMonad.( >>= ) + + let main = + let* _ = put_str "Hello" in + put_str "world!" +end diff --git a/src/content/3.6/code/ocaml/snippet01.ml b/src/content/3.6/code/ocaml/snippet01.ml new file mode 100644 index 00000000..215d19ab --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet01.ml @@ -0,0 +1,5 @@ +module Kleisli (M : MonadJoin) = struct + (* compose *) + let ( <.> ) f g x = f (g x) + let ( >=> ) f g = M.join <.> M.fmap g <.> f +end diff --git a/src/content/3.6/code/ocaml/snippet02.ml b/src/content/3.6/code/ocaml/snippet02.ml new file mode 100644 index 00000000..5c547e4d --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet02.ml @@ -0,0 +1,3 @@ +module Kleisli (M : MonadJoin) = struct + let ( >=> ) f g a = M.join (M.fmap g (f a)) +end diff --git a/src/content/3.6/code/ocaml/snippet03.ml b/src/content/3.6/code/ocaml/snippet03.ml new file mode 100644 index 00000000..22aab74e --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet03.ml @@ -0,0 +1,6 @@ +module type Monoid = sig + type m + + val mappend : m -> m -> m + val mempty : m +end diff --git a/src/content/3.6/code/ocaml/snippet04.ml b/src/content/3.6/code/ocaml/snippet04.ml new file mode 100644 index 00000000..701322cf --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet04.ml @@ -0,0 +1 @@ +val mappend : m -> m -> m diff --git a/src/content/3.6/code/ocaml/snippet05.ml b/src/content/3.6/code/ocaml/snippet05.ml new file mode 100644 index 00000000..3bed3e3f --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet05.ml @@ -0,0 +1 @@ +val mu : (m, m) -> m diff --git a/src/content/3.6/code/ocaml/snippet06.ml b/src/content/3.6/code/ocaml/snippet06.ml new file mode 100644 index 00000000..ecf21abf --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +val eta : unit -> m diff --git a/src/content/3.6/code/ocaml/snippet07.ml b/src/content/3.6/code/ocaml/snippet07.ml new file mode 100644 index 00000000..ed7fb7bb --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet07.ml @@ -0,0 +1,2 @@ +;; +mu (x, mu (y, z)) = mu (mu (x, y), z) diff --git a/src/content/3.6/code/ocaml/snippet08.ml b/src/content/3.6/code/ocaml/snippet08.ml new file mode 100644 index 00000000..07b560e7 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet08.ml @@ -0,0 +1,2 @@ +;; +(compose mu (bimap id mu)) (x, (y, z)) diff --git a/src/content/3.6/code/ocaml/snippet09.ml b/src/content/3.6/code/ocaml/snippet09.ml new file mode 100644 index 00000000..0aa65582 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet09.ml @@ -0,0 +1,2 @@ +;; +(compose mu (bimap mu id)) ((x, y), z) diff --git a/src/content/3.6/code/ocaml/snippet10.ml b/src/content/3.6/code/ocaml/snippet10.ml new file mode 100644 index 00000000..3e389a03 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet10.ml @@ -0,0 +1,2 @@ +;; +compose mu (bimap id mu) = compose mu (bimap mu id) diff --git a/src/content/3.6/code/ocaml/snippet11.ml b/src/content/3.6/code/ocaml/snippet11.ml new file mode 100644 index 00000000..c7ec7603 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet11.ml @@ -0,0 +1 @@ +let alpha ((x, y), z) = x, (y, z) diff --git a/src/content/3.6/code/ocaml/snippet12.ml b/src/content/3.6/code/ocaml/snippet12.ml new file mode 100644 index 00000000..9f6cf8c2 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet12.ml @@ -0,0 +1,2 @@ +;; +compose mu (compose (bimap id mu) alpha) = compose mu (bimap mu id) diff --git a/src/content/3.6/code/ocaml/snippet13.ml b/src/content/3.6/code/ocaml/snippet13.ml new file mode 100644 index 00000000..91327957 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet13.ml @@ -0,0 +1,2 @@ +;; +mu (eta (), x) = x mu (x, eta ()) = x diff --git a/src/content/3.6/code/ocaml/snippet14.ml b/src/content/3.6/code/ocaml/snippet14.ml new file mode 100644 index 00000000..3116d4dc --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet14.ml @@ -0,0 +1,4 @@ +;; +(compose mu (bimap eta id)) ((), x) += lambda ((), x) (compose mu (bimap id eta)) (x, ()) += rho (x, ()) diff --git a/src/content/3.6/code/ocaml/snippet15.ml b/src/content/3.6/code/ocaml/snippet15.ml new file mode 100644 index 00000000..2c045069 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet15.ml @@ -0,0 +1 @@ +let lambda ((), x) = x diff --git a/src/content/3.6/code/ocaml/snippet16.ml b/src/content/3.6/code/ocaml/snippet16.ml new file mode 100644 index 00000000..18865d79 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet16.ml @@ -0,0 +1 @@ +let rho (x, ()) = x diff --git a/src/content/3.6/code/ocaml/snippet17.ml b/src/content/3.6/code/ocaml/snippet17.ml new file mode 100644 index 00000000..a3f9bc76 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet17.ml @@ -0,0 +1,2 @@ +;; +mu.bimap id eta = rho mu.bimap eta id = lambda diff --git a/src/content/3.6/code/ocaml/snippet18.ml b/src/content/3.6/code/ocaml/snippet18.ml new file mode 100644 index 00000000..7a68373c --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet18.ml @@ -0,0 +1 @@ +type ('s, 'a) state = State of ('s -> 'a * 's) diff --git a/src/content/3.6/code/ocaml/snippet19.ml b/src/content/3.6/code/ocaml/snippet19.ml new file mode 100644 index 00000000..6238e10c --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet19.ml @@ -0,0 +1 @@ +type ('s, 'a) prod = Prod of 'a * 's diff --git a/src/content/3.6/code/ocaml/snippet20.ml b/src/content/3.6/code/ocaml/snippet20.ml new file mode 100644 index 00000000..a02babed --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet20.ml @@ -0,0 +1 @@ +type ('s, 'a) reader = Reader of ('s -> 'a) diff --git a/src/content/3.6/code/ocaml/snippet21.ml b/src/content/3.6/code/ocaml/snippet21.ml new file mode 100644 index 00000000..738d6d42 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet21.ml @@ -0,0 +1,15 @@ +module AdjunctionState (S : sig + type s +end) +(F : Functor with type 'a t = (S.s, 'a) prod) +(R : Representable with type 'a t = (S.s, 'a) reader) : Adjunction = +struct + type 'a f = (S.s, 'a) prod + type 'a r = (S.s, 'a) reader + + include F + include R + + let unit a = Reader (fun s -> Prod (a, s)) + let counit (Prod (Reader f, s)) = f s +end diff --git a/src/content/3.6/code/ocaml/snippet22.ml b/src/content/3.6/code/ocaml/snippet22.ml new file mode 100644 index 00000000..7a68373c --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet22.ml @@ -0,0 +1 @@ +type ('s, 'a) state = State of ('s -> 'a * 's) diff --git a/src/content/3.6/code/ocaml/snippet23.ml b/src/content/3.6/code/ocaml/snippet23.ml new file mode 100644 index 00000000..b839b174 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet23.ml @@ -0,0 +1 @@ +let run_state (State f) s = f s diff --git a/src/content/3.6/code/ocaml/snippet24.ml b/src/content/3.6/code/ocaml/snippet24.ml new file mode 100644 index 00000000..4671cf39 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet24.ml @@ -0,0 +1,2 @@ +val ssa : ('s, ('s, 'a) state) state +val run_state ssa : 's -> (('s, 'a) state, 's) diff --git a/src/content/3.6/code/ocaml/snippet25.ml b/src/content/3.6/code/ocaml/snippet25.ml new file mode 100644 index 00000000..1a557e48 --- /dev/null +++ b/src/content/3.6/code/ocaml/snippet25.ml @@ -0,0 +1,3 @@ +let join : ('s, ('s, 'a) state) state -> ('s, 'a) state = + fun ssa -> State (uncurry run_state <.> run_state ssa) +;; diff --git a/src/content/3.7/code/ocaml/snippet01.ml b/src/content/3.7/code/ocaml/snippet01.ml new file mode 100644 index 00000000..af69af12 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet01.ml @@ -0,0 +1 @@ +'a -> 'b m diff --git a/src/content/3.7/code/ocaml/snippet02.ml b/src/content/3.7/code/ocaml/snippet02.ml new file mode 100644 index 00000000..ea29079f --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +'a w -> 'b diff --git a/src/content/3.7/code/ocaml/snippet03.ml b/src/content/3.7/code/ocaml/snippet03.ml new file mode 100644 index 00000000..2a2cd310 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet03.ml @@ -0,0 +1,5 @@ +module type CoKleisli = sig + type 'a w + + val ( =>= ) : ('a w -> 'b) -> ('b w -> 'c) -> 'a w -> 'c +end diff --git a/src/content/3.7/code/ocaml/snippet04.ml b/src/content/3.7/code/ocaml/snippet04.ml new file mode 100644 index 00000000..e281af01 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet04.ml @@ -0,0 +1 @@ +val extract : 'a w -> 'a diff --git a/src/content/3.7/code/ocaml/snippet05.ml b/src/content/3.7/code/ocaml/snippet05.ml new file mode 100644 index 00000000..1c186972 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet05.ml @@ -0,0 +1,8 @@ +module type Comonad = sig + type 'a w + + include Functor with type 'a t := 'a w + + val extract : 'a w -> 'a + val ( =>= ) : ('a w -> 'b) -> ('b w -> 'c) -> 'a w -> 'c +end diff --git a/src/content/3.7/code/ocaml/snippet06.ml b/src/content/3.7/code/ocaml/snippet06.ml new file mode 100644 index 00000000..a5bce831 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet06.ml @@ -0,0 +1 @@ +'a * 'e -> 'b diff --git a/src/content/3.7/code/ocaml/snippet07.ml b/src/content/3.7/code/ocaml/snippet07.ml new file mode 100644 index 00000000..f90d9e87 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +'a -> ('e -> 'b) diff --git a/src/content/3.7/code/ocaml/snippet08.ml b/src/content/3.7/code/ocaml/snippet08.ml new file mode 100644 index 00000000..10aa8410 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +type ('e, 'a) product = P of 'e * 'a diff --git a/src/content/3.7/code/ocaml/snippet09.ml b/src/content/3.7/code/ocaml/snippet09.ml new file mode 100644 index 00000000..ba933092 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet09.ml @@ -0,0 +1,5 @@ +let ( =>= ) f g (P (e, a)) = + let b = f (P (e, a)) in + let c = g (P (e, b)) in + c +;; diff --git a/src/content/3.7/code/ocaml/snippet10.ml b/src/content/3.7/code/ocaml/snippet10.ml new file mode 100644 index 00000000..3f2ce16f --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet10.ml @@ -0,0 +1 @@ +let extract (P (e, a)) = a diff --git a/src/content/3.7/code/ocaml/snippet11.ml b/src/content/3.7/code/ocaml/snippet11.ml new file mode 100644 index 00000000..ee3d8e9c --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet11.ml @@ -0,0 +1,5 @@ +module CoKleisliImpl = struct +type 'a w +let (=>=) : ('a w -> 'b) -> ('b w -> 'c) -> ('a w -> 'c) = fun f g -> + g ... +end diff --git a/src/content/3.7/code/ocaml/snippet12.ml b/src/content/3.7/code/ocaml/snippet12.ml new file mode 100644 index 00000000..b0a83a19 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet12.ml @@ -0,0 +1 @@ +val extend : ('a w -> 'b) -> 'a w -> 'b w diff --git a/src/content/3.7/code/ocaml/snippet13.ml b/src/content/3.7/code/ocaml/snippet13.ml new file mode 100644 index 00000000..d4d961eb --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet13.ml @@ -0,0 +1,13 @@ +module type CoKleisliExtend = sig + type 'a w + + val extend : ('a w -> 'b) -> 'a w -> 'b w +end + +module CoKleisliImpl (C : CoKleisliExtend) = struct + type 'a w = 'a C.w + + let ( =>= ) : ('a w -> 'b) -> ('b w -> 'c) -> 'a w -> 'c = + fun f g -> compose g (C.extend f) + ;; +end diff --git a/src/content/3.7/code/ocaml/snippet14.ml b/src/content/3.7/code/ocaml/snippet14.ml new file mode 100644 index 00000000..af13ff4f --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet14.ml @@ -0,0 +1 @@ +val duplicate : 'a w -> 'a w w diff --git a/src/content/3.7/code/ocaml/snippet15.ml b/src/content/3.7/code/ocaml/snippet15.ml new file mode 100644 index 00000000..c60267ba --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet15.ml @@ -0,0 +1,58 @@ +module type ComonadBase = sig + type 'a w + + include Functor with type 'a t = 'a w + + val extract : 'a w -> 'a +end + +module type ComonadDuplicate = sig + type 'a w + + val duplicate : 'a w -> 'a w w +end + +module type ComonadExtend = sig + type 'a w + + val extend : ('a w -> 'b) -> 'a w -> 'b w +end + +module type Comonad = sig + type 'a w + + include ComonadBase with type 'a w := 'a w + include ComonadExtend with type 'a w := 'a w + include ComonadDuplicate with type 'a w := 'a w +end + +(* Construct a full comonad instance using one of the following modules *) +module ComonadImplViaExtend : functor + (C : ComonadBase) + (D : ComonadDuplicate with type 'a w = 'a C.w) + -> Comonad with type 'a w = 'a C.w = +functor + (C : ComonadBase) + (D : ComonadDuplicate with type 'a w = 'a C.w) + -> + struct + include C + include D + + let extend f wa = (C.fmap f) (D.duplicate wa) + end + +module ComonadImplViaDuplicate : functor + (C : ComonadBase) + (E : ComonadExtend with type 'a w = 'a C.w) + -> Comonad with type 'a w = 'a C.w = +functor + (C : ComonadBase) + (E : ComonadExtend with type 'a w = 'a C.w) + -> + struct + include C + include E + + let duplicate (wa : 'a w) : 'a w w = E.extend id wa + end diff --git a/src/content/3.7/code/ocaml/snippet16.ml b/src/content/3.7/code/ocaml/snippet16.ml new file mode 100644 index 00000000..4d0a3169 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet16.ml @@ -0,0 +1 @@ +type 'a stream = Cons of 'a * 'a stream Lazy.t diff --git a/src/content/3.7/code/ocaml/snippet17.ml b/src/content/3.7/code/ocaml/snippet17.ml new file mode 100644 index 00000000..ce2860a8 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet17.ml @@ -0,0 +1,8 @@ +module StreamFunctor : Functor with type 'a t = 'a stream = struct + type 'a t = 'a stream + + let rec fmap f = function + | Cons (x, xs) -> + Cons (f x, Lazy.from_val (fmap f (Lazy.force xs))) + ;; +end diff --git a/src/content/3.7/code/ocaml/snippet18.ml b/src/content/3.7/code/ocaml/snippet18.ml new file mode 100644 index 00000000..536843cb --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet18.ml @@ -0,0 +1 @@ +let extract (Cons (x, _)) = x diff --git a/src/content/3.7/code/ocaml/snippet19.ml b/src/content/3.7/code/ocaml/snippet19.ml new file mode 100644 index 00000000..f6bb8aea --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet19.ml @@ -0,0 +1,3 @@ +let rec duplicate (Cons (x, xs)) = + Cons (Cons (x, xs), Lazy.from_val (duplicate (Lazy.force xs))) +;; diff --git a/src/content/3.7/code/ocaml/snippet20.ml b/src/content/3.7/code/ocaml/snippet20.ml new file mode 100644 index 00000000..672004c3 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet20.ml @@ -0,0 +1,24 @@ +(* Implement Extract *) +module StreamComonadBase (F : Functor with type 'a t = 'a stream) : + ComonadBase with type 'a w = 'a stream = struct + type 'a w = 'a stream + + include F + + let extract (Cons (x, _)) = x +end + +(* Implement duplicate *) +module StreamComonadDuplicate : + ComonadDuplicate with type 'a w = 'a stream = struct + type 'a w = 'a stream + + let rec duplicate (Cons (x, xs)) = + Cons (Cons (x, xs), Lazy.from_val (duplicate (Lazy.force xs))) + ;; +end + +(* Generate full Comonad Instance *) +module StreamComonad : Comonad with type 'a w = 'a stream = + ComonadImplViaExtend + (StreamComonadBase (StreamFunctor)) (StreamComonadDuplicate) diff --git a/src/content/3.7/code/ocaml/snippet21.ml b/src/content/3.7/code/ocaml/snippet21.ml new file mode 100644 index 00000000..cbc835a1 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet21.ml @@ -0,0 +1 @@ +let tail (Cons (_, xs)) = Lazy.force xs diff --git a/src/content/3.7/code/ocaml/snippet22.ml b/src/content/3.7/code/ocaml/snippet22.ml new file mode 100644 index 00000000..fe1c591b --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet22.ml @@ -0,0 +1,3 @@ +let rec sum_s n (Cons (x, xs)) = + if n <= 0 then 0 else x + sum_s (n - 1) (Lazy.force xs) +;; diff --git a/src/content/3.7/code/ocaml/snippet23.ml b/src/content/3.7/code/ocaml/snippet23.ml new file mode 100644 index 00000000..aaadd460 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet23.ml @@ -0,0 +1 @@ +let average n stm = Float.(of_int (sum_s n stm) /. of_int n) diff --git a/src/content/3.7/code/ocaml/snippet24.ml b/src/content/3.7/code/ocaml/snippet24.ml new file mode 100644 index 00000000..708d5ab7 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet24.ml @@ -0,0 +1 @@ +let moving_average n = StreamComonad.extend (average n) diff --git a/src/content/3.7/code/ocaml/snippet25.ml b/src/content/3.7/code/ocaml/snippet25.ml new file mode 100644 index 00000000..69cf1d80 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet25.ml @@ -0,0 +1,6 @@ +module type Comonoid = sig + type m + + val split : m -> m * m + val destroy : m -> unit +end diff --git a/src/content/3.7/code/ocaml/snippet26.ml b/src/content/3.7/code/ocaml/snippet26.ml new file mode 100644 index 00000000..841292ac --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet26.ml @@ -0,0 +1 @@ +let destroy _ = () diff --git a/src/content/3.7/code/ocaml/snippet27.ml b/src/content/3.7/code/ocaml/snippet27.ml new file mode 100644 index 00000000..2cc78523 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet27.ml @@ -0,0 +1 @@ +let split x = f x, g x diff --git a/src/content/3.7/code/ocaml/snippet28.ml b/src/content/3.7/code/ocaml/snippet28.ml new file mode 100644 index 00000000..c51071a4 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet28.ml @@ -0,0 +1,11 @@ +(* lambda is the left unitor and rho is the right unitor *) +(* <.> is used as compose below *) + +;; +lambda +<.> bimap destroy id +<.> split += id rho +<.> bimap id destroy +<.> split += id diff --git a/src/content/3.7/code/ocaml/snippet29.ml b/src/content/3.7/code/ocaml/snippet29.ml new file mode 100644 index 00000000..739b7c7e --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet29.ml @@ -0,0 +1,5 @@ +;; +lambda (bimap destroy id (split x)) += lambda (bimap destroy id (f x, g x)) += lambda ((), g x) += g x diff --git a/src/content/3.7/code/ocaml/snippet30.ml b/src/content/3.7/code/ocaml/snippet30.ml new file mode 100644 index 00000000..cb3af6af --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet30.ml @@ -0,0 +1 @@ +let split x = x, x diff --git a/src/content/3.7/code/ocaml/snippet31.ml b/src/content/3.7/code/ocaml/snippet31.ml new file mode 100644 index 00000000..1ea16bfa --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet31.ml @@ -0,0 +1 @@ +type ('s, 'a) store = Store of (('s -> 'a) * 's) diff --git a/src/content/3.7/code/ocaml/snippet32.ml b/src/content/3.7/code/ocaml/snippet32.ml new file mode 100644 index 00000000..d34f3861 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet32.ml @@ -0,0 +1 @@ +let counit (Prod (Reader f, s)) = f s diff --git a/src/content/3.7/code/ocaml/snippet33.ml b/src/content/3.7/code/ocaml/snippet33.ml new file mode 100644 index 00000000..2b634cbe --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet33.ml @@ -0,0 +1 @@ +let extract (Store (f, s)) = f s diff --git a/src/content/3.7/code/ocaml/snippet34.ml b/src/content/3.7/code/ocaml/snippet34.ml new file mode 100644 index 00000000..b4c2bf4e --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet34.ml @@ -0,0 +1 @@ +let unit a = Reader (fun s -> Prod (a, s)) diff --git a/src/content/3.7/code/ocaml/snippet35.ml b/src/content/3.7/code/ocaml/snippet35.ml new file mode 100644 index 00000000..f8d830b4 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet35.ml @@ -0,0 +1 @@ +let make_store f s = Store (f, s) diff --git a/src/content/3.7/code/ocaml/snippet36.ml b/src/content/3.7/code/ocaml/snippet36.ml new file mode 100644 index 00000000..054bc6cb --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet36.ml @@ -0,0 +1 @@ +let duplicate (Store (f, s)) = Store (make_store f, s) diff --git a/src/content/3.7/code/ocaml/snippet37.ml b/src/content/3.7/code/ocaml/snippet37.ml new file mode 100644 index 00000000..d40a5bb5 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet37.ml @@ -0,0 +1,28 @@ +module StoreComonadBase (S : sig + type s +end) +(F : Functor with type 'a t = (S.s, 'a) store) : + ComonadBase with type 'a w = (S.s, 'a) store = struct + type 'a w = (S.s, 'a) store + + include F + + let extract (Store (f, s)) = f s +end + +module StoreComonadDuplicate (S : sig + type s +end) : ComonadDuplicate with type 'a w = (S.s, 'a) store = struct + type 'a w = (S.s, 'a) store + + let duplicate (Store (f, s)) = Store (make_store f, s) +end + +(* Generate Full comonad *) +module StoreComonad (S : sig + type s +end) +(F : Functor with type 'a t = (S.s, 'a) store) : + Comonad with type 'a w = (S.s, 'a) store = + ComonadImplViaExtend + (StoreComonadBase (S) (F)) (StoreComonadDuplicate (S)) diff --git a/src/content/3.7/code/ocaml/snippet38.ml b/src/content/3.7/code/ocaml/snippet38.ml new file mode 100644 index 00000000..f37d3a82 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet38.ml @@ -0,0 +1 @@ +'a -> ('s, 'a) store diff --git a/src/content/3.7/code/ocaml/snippet39.ml b/src/content/3.7/code/ocaml/snippet39.ml new file mode 100644 index 00000000..90a0b7a0 --- /dev/null +++ b/src/content/3.7/code/ocaml/snippet39.ml @@ -0,0 +1,2 @@ +val get : 'a -> 's +val set : 'a -> 's -> 'a diff --git a/src/content/3.8/code/ocaml/snippet01.ml b/src/content/3.8/code/ocaml/snippet01.ml new file mode 100644 index 00000000..8ff3f2f7 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet01.ml @@ -0,0 +1,7 @@ +module type Algebra = functor + (F : sig + type 'a f + end) + -> sig + type 'a algebra = 'a F.f -> 'a +end diff --git a/src/content/3.8/code/ocaml/snippet02.ml b/src/content/3.8/code/ocaml/snippet02.ml new file mode 100644 index 00000000..83350331 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet02.ml @@ -0,0 +1,3 @@ +type 'a mon_f = + | MEmpty + | Mappend of ('a * 'a) diff --git a/src/content/3.8/code/ocaml/snippet03.ml b/src/content/3.8/code/ocaml/snippet03.ml new file mode 100644 index 00000000..434a015a --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet03.ml @@ -0,0 +1,6 @@ +type 'a ring_f = + | RZero + | ROne + | RAdd of ('a * 'a) + | RMul of ('a * 'a) + | RNeg of 'a diff --git a/src/content/3.8/code/ocaml/snippet04.ml b/src/content/3.8/code/ocaml/snippet04.ml new file mode 100644 index 00000000..8566e950 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet04.ml @@ -0,0 +1,13 @@ +module Ring = struct + module RingAlg = Algebra (struct + type 'a f = 'a ring_f + end) + + let eval_z : 'a RingAlg.algebra = function + | RZero -> 0 + | ROne -> 1 + | RAdd (m, n) -> m + n + | RMul (m, n) -> m * n + | RNeg n -> -n + ;; +end diff --git a/src/content/3.8/code/ocaml/snippet05.ml b/src/content/3.8/code/ocaml/snippet05.ml new file mode 100644 index 00000000..75ce0b06 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet05.ml @@ -0,0 +1,6 @@ +type expr = + | RZero + | ROne + | RAdd of (expr * expr) + | RMul of (expr * expr) + | RNeg of expr diff --git a/src/content/3.8/code/ocaml/snippet06.ml b/src/content/3.8/code/ocaml/snippet06.ml new file mode 100644 index 00000000..d3525619 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet06.ml @@ -0,0 +1,7 @@ +let rec eval_z : expr -> int = function + | RZero -> 0 + | ROne -> 1 + | RAdd (e1, e2) -> eval_z e1 + eval_z e2 + | RMul (e1, e2) -> eval_z e1 * eval_z e2 + | RNeg e -> -eval_z e +;; diff --git a/src/content/3.8/code/ocaml/snippet07.ml b/src/content/3.8/code/ocaml/snippet07.ml new file mode 100644 index 00000000..953e9788 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +type 'a ring_f1 = 'a ring_f ring_f diff --git a/src/content/3.8/code/ocaml/snippet08.ml b/src/content/3.8/code/ocaml/snippet08.ml new file mode 100644 index 00000000..6ed2cc07 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet08.ml @@ -0,0 +1 @@ +type 'a ring_f2 = 'a ring_f ring_f ring_f diff --git a/src/content/3.8/code/ocaml/snippet09.ml b/src/content/3.8/code/ocaml/snippet09.ml new file mode 100644 index 00000000..e9b304bc --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet09.ml @@ -0,0 +1 @@ +type 'a ring_f2 = 'a ring_f ring_f1 diff --git a/src/content/3.8/code/ocaml/snippet10.ml b/src/content/3.8/code/ocaml/snippet10.ml new file mode 100644 index 00000000..c57c26f7 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet10.ml @@ -0,0 +1,3 @@ +module Fix (F : Functor) = struct + type 'a fix = Fix of 'a fix F.t +end diff --git a/src/content/3.8/code/ocaml/snippet11.ml b/src/content/3.8/code/ocaml/snippet11.ml new file mode 100644 index 00000000..34a157fe --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet11.ml @@ -0,0 +1,3 @@ +module Fix (F : Functor) = struct + type 'a fix = In of 'a fix F.t +end diff --git a/src/content/3.8/code/ocaml/snippet12.ml b/src/content/3.8/code/ocaml/snippet12.ml new file mode 100644 index 00000000..4e62e65b --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet12.ml @@ -0,0 +1,5 @@ +module Fix (F : Functor) = struct + type 'a fix = Fix of 'a fix F.t + + let fix : 'a fix F.t -> 'a fix = fun f -> Fix f +end diff --git a/src/content/3.8/code/ocaml/snippet13.ml b/src/content/3.8/code/ocaml/snippet13.ml new file mode 100644 index 00000000..6cb96728 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet13.ml @@ -0,0 +1,5 @@ +module Fix (F : Functor) = struct + type 'a fix = Fix of 'a fix F.t + + let unfix : 'a fix -> 'a fix F.t = fun (Fix f) -> f +end diff --git a/src/content/3.8/code/ocaml/snippet14.ml b/src/content/3.8/code/ocaml/snippet14.ml new file mode 100644 index 00000000..dda7ab43 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet14.ml @@ -0,0 +1,3 @@ +type 'a nat_f = + | ZeroF + | SuccF of 'a diff --git a/src/content/3.8/code/ocaml/snippet15.ml b/src/content/3.8/code/ocaml/snippet15.ml new file mode 100644 index 00000000..0749a6fb --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet15.ml @@ -0,0 +1,3 @@ +type nat = + | Zero + | Succ of nat diff --git a/src/content/3.8/code/ocaml/snippet16.ml b/src/content/3.8/code/ocaml/snippet16.ml new file mode 100644 index 00000000..322e356a --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet16.ml @@ -0,0 +1,10 @@ +module Cata (F : Functor) = struct + type 'a fix = Fix of 'a fix F.t + + let fix : 'a fix F.t -> 'a fix = fun f -> Fix f + let unfix : 'a fix -> 'a fix F.t = fun (Fix f) -> f + + let rec cata : ('a F.t -> 'a) -> 'a fix -> 'a = + fun alg fixf -> alg (F.fmap (cata alg) (unfix fixf)) + ;; +end diff --git a/src/content/3.8/code/ocaml/snippet17.ml b/src/content/3.8/code/ocaml/snippet17.ml new file mode 100644 index 00000000..dda7ab43 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet17.ml @@ -0,0 +1,3 @@ +type 'a nat_f = + | ZeroF + | SuccF of 'a diff --git a/src/content/3.8/code/ocaml/snippet18.ml b/src/content/3.8/code/ocaml/snippet18.ml new file mode 100644 index 00000000..2252f09d --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet18.ml @@ -0,0 +1,4 @@ +let rec fib = function + | ZeroF -> 1, 1 + | SuccF (m, n) -> n, m + n +;; diff --git a/src/content/3.8/code/ocaml/snippet19.ml b/src/content/3.8/code/ocaml/snippet19.ml new file mode 100644 index 00000000..1ad95f48 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet19.ml @@ -0,0 +1,3 @@ +type ('e, 'a) list_f = + | NilF + | ConsF of ('e * 'a) diff --git a/src/content/3.8/code/ocaml/snippet20.ml b/src/content/3.8/code/ocaml/snippet20.ml new file mode 100644 index 00000000..88e276a2 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet20.ml @@ -0,0 +1,3 @@ +type 'e list' = + | Nil + | Cons of ('e * 'e list') diff --git a/src/content/3.8/code/ocaml/snippet21.ml b/src/content/3.8/code/ocaml/snippet21.ml new file mode 100644 index 00000000..6513583f --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet21.ml @@ -0,0 +1,4 @@ +let len_alg = function + | ConsF (e, n) -> n + 1 + | NilF -> 0 +;; diff --git a/src/content/3.8/code/ocaml/snippet22.ml b/src/content/3.8/code/ocaml/snippet22.ml new file mode 100644 index 00000000..e7a8b588 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet22.ml @@ -0,0 +1 @@ +let length xs = List.fold_right (fun e n -> n + 1) xs 0 diff --git a/src/content/3.8/code/ocaml/snippet23.ml b/src/content/3.8/code/ocaml/snippet23.ml new file mode 100644 index 00000000..1bfaf81c --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet23.ml @@ -0,0 +1,4 @@ +let sum_alg = function + | ConsF (e, s) -> e +. s + | NilF -> 0.0 +;; diff --git a/src/content/3.8/code/ocaml/snippet24.ml b/src/content/3.8/code/ocaml/snippet24.ml new file mode 100644 index 00000000..0fbbedcc --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet24.ml @@ -0,0 +1 @@ +let sum xs = List.fold_right (fun e s -> e +. s) xs 0.0 diff --git a/src/content/3.8/code/ocaml/snippet25.ml b/src/content/3.8/code/ocaml/snippet25.ml new file mode 100644 index 00000000..73c75171 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet25.ml @@ -0,0 +1,7 @@ +module Ana (F : Functor) = struct + type 'a fix = Fix of 'a fix F.t + + let rec ana : ('a -> 'a F.t) -> 'a -> 'a fix = + fun coalg a -> Fix (F.fmap (ana coalg) (coalg a)) + ;; +end diff --git a/src/content/3.8/code/ocaml/snippet26.ml b/src/content/3.8/code/ocaml/snippet26.ml new file mode 100644 index 00000000..5bea72c7 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet26.ml @@ -0,0 +1,11 @@ +type ('e, 'a) stream_f = StreamF of ('e * 'a) + +module Stream_Functor (E : sig + type e +end) : Functor with type 'a t = (E.e, 'a) stream_f = struct + type 'a t = (E.e, 'a) stream_f + + let fmap f = function + | StreamF (e, a) -> StreamF (e, f a) + ;; +end diff --git a/src/content/3.8/code/ocaml/snippet27.ml b/src/content/3.8/code/ocaml/snippet27.ml new file mode 100644 index 00000000..719d83cd --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet27.ml @@ -0,0 +1 @@ +type 'e stream = Stream of ('e * 'e stream) diff --git a/src/content/3.8/code/ocaml/snippet28.ml b/src/content/3.8/code/ocaml/snippet28.ml new file mode 100644 index 00000000..a757760e --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet28.ml @@ -0,0 +1,10 @@ +(* OCaml library `gen` provides useful helpers for + potentially infinite iterators. You can install it + with `opam install gen`. To use it in the toplevel, + you need to `#require "gen"` *) +let era : int Gen.t -> (int, int Gen.t) stream_f = + fun ilist -> + let notdiv p n = n mod p != 0 in + let p = Gen.get_exn ilist in + StreamF (p, Gen.filter (notdiv p) ilist) +;; diff --git a/src/content/3.8/code/ocaml/snippet29.ml b/src/content/3.8/code/ocaml/snippet29.ml new file mode 100644 index 00000000..09ad9e29 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet29.ml @@ -0,0 +1,10 @@ +module Stream_Int = Stream_Functor (struct + type e = int +end) + +module Ana_Stream = Ana (Stream_Int) + +(* The fixpoint translated to OCaml is eager in its evaluation. +Hence, executing the following function will cause overflow. +So, wrapping it inside a lazy *) +let primes = lazy (Ana_Stream.ana era (Gen.init (fun i -> i + 2))) diff --git a/src/content/3.8/code/ocaml/snippet30.ml b/src/content/3.8/code/ocaml/snippet30.ml new file mode 100644 index 00000000..869e9e00 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet30.ml @@ -0,0 +1,14 @@ +module List_C (E : sig + type e +end) = +struct + module Stream_F : Functor with type 'a t = (E.e, 'a) stream_f = + Stream_Functor (E) + + module Cata_Stream = Cata (Stream_F) + + let to_list_c : E.e list Cata_Stream.fix -> E.e list = + fun s_fix -> + Cata_Stream.cata (fun (StreamF (e, a)) -> e :: a) s_fix + ;; +end diff --git a/src/content/3.8/code/ocaml/snippet31.ml b/src/content/3.8/code/ocaml/snippet31.ml new file mode 100644 index 00000000..bdc9afb7 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet31.ml @@ -0,0 +1,2 @@ +(* Gen.t is used to represent infinite data structures like haskell's lazy list *) +val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a Gen.t diff --git a/src/content/3.8/code/ocaml/snippet32.ml b/src/content/3.8/code/ocaml/snippet32.ml new file mode 100644 index 00000000..47300711 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet32.ml @@ -0,0 +1,2 @@ +val set : 'a -> 's -> 'a +val get : 'a -> 's diff --git a/src/content/3.8/code/ocaml/snippet33.ml b/src/content/3.8/code/ocaml/snippet33.ml new file mode 100644 index 00000000..caf74ebe --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet33.ml @@ -0,0 +1 @@ +(a, (s, s -> a)) diff --git a/src/content/3.8/code/ocaml/snippet34.ml b/src/content/3.8/code/ocaml/snippet34.ml new file mode 100644 index 00000000..f37d3a82 --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet34.ml @@ -0,0 +1 @@ +'a -> ('s, 'a) store diff --git a/src/content/3.8/code/ocaml/snippet35.ml b/src/content/3.8/code/ocaml/snippet35.ml new file mode 100644 index 00000000..3b82e61d --- /dev/null +++ b/src/content/3.8/code/ocaml/snippet35.ml @@ -0,0 +1,2 @@ +(* Store is the comonad version of State *) +type ('s, 'a) store = Store of ('s -> 'a) * 's diff --git a/src/content/3.9/code/ocaml/snippet01.ml b/src/content/3.9/code/ocaml/snippet01.ml new file mode 100644 index 00000000..ace36491 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet01.ml @@ -0,0 +1,2 @@ +;; +compose alg return = id compose alg join = compose alg (fmap alg) diff --git a/src/content/3.9/code/ocaml/snippet02.ml b/src/content/3.9/code/ocaml/snippet02.ml new file mode 100644 index 00000000..82318983 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet02.ml @@ -0,0 +1 @@ +val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b diff --git a/src/content/3.9/code/ocaml/snippet03.ml b/src/content/3.9/code/ocaml/snippet03.ml new file mode 100644 index 00000000..35f55012 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet03.ml @@ -0,0 +1,4 @@ +(* List module in the OCaml standard library accepts list before z *) + +;; +List.fold_right f [ x ] z = f x z diff --git a/src/content/3.9/code/ocaml/snippet04.ml b/src/content/3.9/code/ocaml/snippet04.ml new file mode 100644 index 00000000..db7bea0a --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet04.ml @@ -0,0 +1,2 @@ +;; +f x z = x diff --git a/src/content/3.9/code/ocaml/snippet05.ml b/src/content/3.9/code/ocaml/snippet05.ml new file mode 100644 index 00000000..8152bba3 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet05.ml @@ -0,0 +1,3 @@ +module Kleisli_Composition (T : MonadJoin) = struct + let h g f = T.join <.> T.fmap g <.> f +end diff --git a/src/content/3.9/code/ocaml/snippet06.ml b/src/content/3.9/code/ocaml/snippet06.ml new file mode 100644 index 00000000..59db33e1 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet06.ml @@ -0,0 +1,3 @@ +module C_to_CT (T : Monad) = struct + let on_objects = T.return <.> f +end diff --git a/src/content/3.9/code/ocaml/snippet07.ml b/src/content/3.9/code/ocaml/snippet07.ml new file mode 100644 index 00000000..0933fe58 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet07.ml @@ -0,0 +1 @@ +type ('s, 'a) store = Store of ('s -> 'a) * 's diff --git a/src/content/3.9/code/ocaml/snippet08.ml b/src/content/3.9/code/ocaml/snippet08.ml new file mode 100644 index 00000000..a927377a --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet08.ml @@ -0,0 +1,15 @@ +module Store_comonad (S : sig + type s +end) +(F : Functor with type 'a t = (S.s, 'a) store) : + Comonad with type 'a w = (S.s, 'a) store = struct + type 'a w = (S.s, 'a) store + + include F + + let extract : 'a w -> 'a = fun (Store (f, s)) -> f s + + let duplicate : 'a w -> 'a w w = + fun (Store (f, s)) -> Store ((fun s -> Store (f, s)), s) + ;; +end diff --git a/src/content/3.9/code/ocaml/snippet09.ml b/src/content/3.9/code/ocaml/snippet09.ml new file mode 100644 index 00000000..f9cd3522 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet09.ml @@ -0,0 +1,8 @@ +module Store_Functor (S : sig + type s +end) : Functor with type 'a t = (S.s, 'a) store = struct + type 'a w = (S.s, 'a) store + type 'a t = 'a w + + let fmap g (Store (f, s)) = Store (compose g f, s) +end diff --git a/src/content/3.9/code/ocaml/snippet10.ml b/src/content/3.9/code/ocaml/snippet10.ml new file mode 100644 index 00000000..6f8f3106 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet10.ml @@ -0,0 +1,4 @@ +(* Assume <.> acts as compose *) + +;; +Store (coalg_store <.> set a, get a) diff --git a/src/content/3.9/code/ocaml/snippet11.ml b/src/content/3.9/code/ocaml/snippet11.ml new file mode 100644 index 00000000..59543f7e --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet11.ml @@ -0,0 +1,2 @@ +;; +Store ((fun s -> Store (set a, s)), get a) diff --git a/src/content/3.9/code/ocaml/snippet12.ml b/src/content/3.9/code/ocaml/snippet12.ml new file mode 100644 index 00000000..60a80262 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet12.ml @@ -0,0 +1,2 @@ +(* Pseudo OCaml *) +let coalg_store (set a s) = Store ((set a), s) diff --git a/src/content/3.9/code/ocaml/snippet13.ml b/src/content/3.9/code/ocaml/snippet13.ml new file mode 100644 index 00000000..a5dcc0f6 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet13.ml @@ -0,0 +1,4 @@ +(* Expaning coalg_store *) + +;; +Store (set (set a s), get (set a s)) = Store (set a, s) diff --git a/src/content/3.9/code/ocaml/snippet14.ml b/src/content/3.9/code/ocaml/snippet14.ml new file mode 100644 index 00000000..f9fecb07 --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet14.ml @@ -0,0 +1,2 @@ +;; +set (set a s) = set a diff --git a/src/content/3.9/code/ocaml/snippet15.ml b/src/content/3.9/code/ocaml/snippet15.ml new file mode 100644 index 00000000..62ce811c --- /dev/null +++ b/src/content/3.9/code/ocaml/snippet15.ml @@ -0,0 +1,2 @@ +;; +get (set a s) = s diff --git a/src/content/ocaml/colophon.tex b/src/content/ocaml/colophon.tex new file mode 100644 index 00000000..707e5982 --- /dev/null +++ b/src/content/ocaml/colophon.tex @@ -0,0 +1,2 @@ +OCaml code translation was done by \urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{Arulselvan Madhavan} +and reviewed by \urlref{http://www.mseri.me}{Marcello Seri} and \urlref{https://github.com/XVilka}{Anton Kochkov}. \ No newline at end of file diff --git a/src/content/ocaml/editor-note.tex b/src/content/ocaml/editor-note.tex new file mode 100644 index 00000000..6c54cb55 --- /dev/null +++ b/src/content/ocaml/editor-note.tex @@ -0,0 +1,27 @@ +% !TEX root = ctfp-print.tex + +\lettrine[lhang=0.17]{T}{his is the} OCaml edition of \emph{Category Theory for Programmers}. +It's been a tremendous success, making Bartosz Milewski's blog post series available as a nicely- +typeset \acronym{PDF}, as well as a hardcover book. There have been numerous contributions made +to improve the book, by fixing typos and errors, as well as translating the code snippets into +other programming languages. + +I am thrilled to present this edition of the book, containing the original Haskell code, followed by +its OCaml counterpart. The OCaml code snippets were generously provided by +\urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{ocaml-ctfp} contributors, slightly +modified to suit the format of this book. + +To support code snippets in multiple languages, I am using a \LaTeX{} macro to load the code snippets +from external files. This allows easily extending the book with other languages, while leaving the +original text intact. Which is why you should mentally append the words ``and OCaml'' whenever you see +``in Haskell'' in the text. + +The code is laid out in the following manner: the original Haskell code, followed by OCaml code. +To distinguish between them, the code snippets are braced from the left with a vertical bar, in the primary +color of the language's logo, \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/haskell.png}}, +and \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/ocaml.png}} respectively, e.g.: + +\srcsnippet{content/1.1/code/haskell/snippet03.hs}{blue}{haskell} +\unskip +\srcsnippet{content/1.1/code/ocaml/snippet03.ml}{orange}{ocaml} +\NoIndentAfterThis \ No newline at end of file diff --git a/src/ctfp-print-ocaml.tex b/src/ctfp-print-ocaml.tex new file mode 100644 index 00000000..e1a939ea --- /dev/null +++ b/src/ctfp-print-ocaml.tex @@ -0,0 +1,3 @@ +\input{opt-ocaml} +\input{ctfp-print} +\input{postamble} \ No newline at end of file diff --git a/src/ctfp-reader-ocaml.tex b/src/ctfp-reader-ocaml.tex new file mode 100644 index 00000000..d4f6ad81 --- /dev/null +++ b/src/ctfp-reader-ocaml.tex @@ -0,0 +1,3 @@ +\input{opt-ocaml} +\input{ctfp-reader} +\input{postamble} \ No newline at end of file diff --git a/src/fig/icons/ocaml.png b/src/fig/icons/ocaml.png new file mode 100644 index 0000000000000000000000000000000000000000..486fd93b487a912196444553a5348c6881d1cec7 GIT binary patch literal 15789 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 fN*xg(H-W3S>=p#fw=2QFS_3Ld8c&K9%!B_Q0n$