{"id":13726448,"url":"https://github.com/alhassy/OCamlCheatSheet","last_synced_at":"2025-05-07T21:32:40.455Z","repository":{"id":108701417,"uuid":"149482969","full_name":"alhassy/OCamlCheatSheet","owner":"alhassy","description":"Reference of basic commands to get comfortable with OCaml.","archived":false,"fork":false,"pushed_at":"2019-07-13T18:48:42.000Z","size":1476,"stargazers_count":80,"open_issues_count":0,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-11T21:51:07.004Z","etag":null,"topics":["cheatsheet","html","metaocaml","ocaml","pdf","reference"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alhassy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-09-19T16:50:39.000Z","updated_at":"2024-10-08T12:52:50.000Z","dependencies_parsed_at":"2023-03-13T14:24:07.887Z","dependency_job_id":null,"html_url":"https://github.com/alhassy/OCamlCheatSheet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2FOCamlCheatSheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2FOCamlCheatSheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2FOCamlCheatSheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2FOCamlCheatSheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alhassy","download_url":"https://codeload.github.com/alhassy/OCamlCheatSheet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224654278,"owners_count":17347714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cheatsheet","html","metaocaml","ocaml","pdf","reference"],"created_at":"2024-08-03T01:03:05.177Z","updated_at":"2024-11-14T16:33:51.648Z","avatar_url":"https://github.com/alhassy.png","language":null,"readme":"\u003ch1\u003e OCamlCheatSheet \u003c/h1\u003e\n\n\u003cdiv class=\"org-center\"\u003e\n[◆ Website ◆](https://alhassy.github.io/OCamlCheatSheet/)\n\u003c/div\u003e\n\n**The listing sheet, as PDF, can be found\n[here](CheatSheet.pdf)**,\nor as a [single column portrait](CheatSheet_Portrait.pdf),\nwhile below is an unruly html rendition.\n\nThis reference sheet is built from a\n[CheatSheets with Org-mode](https://github.com/alhassy/CheatSheet)\nsystem.\n\n\n# Table of Contents\n\n1.  [Emacs Setup](#org94e9f39):HTML:\n2.  [Arithmetic](#org849a066)\n3.  [Functions \u0026 Variables](#org1344014)\n4.  [Booleans](#orgd3de3b7)\n5.  [Strings](#org10d734c)\n6.  [Records](#org262bbec)\n7.  [Variants and Pattern Matching](#org6608e6d)\n8.  [Tuples and Lists](#org67af557)\n9.  [Options](#orgbe4f146)\n10. [Imperative Programming \u0026#x2014;Sequencing \u0026 `main`](#org8dae4ac)\n11. [Imperative Programming \u0026#x2014;Arrays](#orge48c00e)\n12. [Imperative Programming \u0026#x2014;Unit Type](#orgbbe1203)\n13. [Imperative programming \u0026#x2014;Mutable records](#org186bdec)\n14. [Imperative Programming \u0026#x2014;References](#org7589654)\n15. [Modules](#orgf9e076f)\n16. [Functors](#orgacb6c97)\n17. [First-Class Modules](#org1f3bead)\n18. [*Locally* Abstract Types \u0026 ‘[un]bundling’](#org02ce931)\n19. [Metaprogramming with MetaOCaml](#org2064485)\n20. [Reads](#orgdc9edf1)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nOCaml is a strict language;\nit is strongly typed where types are inferred.\n\nI may write explicit type annotations below for demonstration\nor clarity purposes.\n\n    (* Using explicit type annotations *)\n    let x : int = 3;;\n    let f (x : int) (y : string) (r : 'a) : float = 3.14;;\n\nOnly when interacting with the top-level interpreter,\ncommands must be terminated by `;;`.\nOCaml uses `;` as an expression *separator* \u0026#x2014;not a terminator!\n\nMy Emacs setup for OCaml can be found on this [CheatSheet's repo](https://github.com/alhassy/OCamlCheatSheet).\n\n\n\u003ca id=\"org94e9f39\"\u003e\u003c/a\u003e\n\n# Emacs Setup     :HTML:\n\nFirst, let's get [Meta]OCaml.\n\n    ;; Easiest on my machine.\n    ;; (async-shell-command \"brew install ocaml\")\n\n    ;; The OCaml package manager: https://opam.ocaml.org/\n    (async-shell-command \"brew install opam\") ;; version 2.0.4\n\n    ;; (async-shell-command \"opam switch create 4.07.1\")  ;; install ocaml\n    (async-shell-command \"opam switch create 4.07.1+BER\") ;; install metaocaml\n\nLet's set this up for Emacs.\n\n    (use-package tuareg :demand t)              ;; Emacs’ OCaml mode\n    (setq tuareg-support-metaocaml t)           ;; Only handles metaocaml syntax\n    (setq org-babel-ocaml-command \"metaocaml\")  ;; Different command for metaocaml\n\nLet's obtain `ocp-indent` \u0026#x2014;OCaml's indentation tool that indents the same even if\nco-workers use a different editor\u0026#x2014; and [merlin](https://github.com/ocaml/merlin/wiki/emacs-from-scratch) which provides interactive feedback\nincluding context-aware completion and jumping to definitions.\n\n    (async-shell-command \"time opam install ocp-indent merlin\") ;; real 1m33.636s\n    (use-package merlin)\n    (add-hook 'tuareg-mode-hook #'merlin-mode)\n    (with-eval-after-load 'merlin (setq merlin-command 'opam))\n\nNow entering, say, `List.` brings a pop-up completion menu for the\ncontents of the list module.\n\n\u0026#x2014;In org-src blocks, you need to enter the ocaml mode, via `C-c '`.\n\n\n\u003ca id=\"org849a066\"\u003e\u003c/a\u003e\n\n# Arithmetic\n\nOperations on floats have a ‘.’ suffix.\n\n    8 / 3;;      (* 2 *)\n    8 /. 3;;     (* Type error: /. is for floats *)\n    8.0 /. 3.0;; (* 2.6666… *)\n\n\n\u003ca id=\"org1344014\"\u003e\u003c/a\u003e\n\n# Functions \u0026 Variables\n\n  A function is declared with the `let` keyword\n\u0026#x2014;variables are functions of zero arguments.\nFunction \u0026 varaible names *must* begin with a lowercase letter, and may use \\_ or `'`.\n\n-   They cannot begin with capital letters or numbers, or contain dashes!\n-   Functions are like variables, but with arguments, so the same syntax applies.\n\n\u003cdiv class=\"parallel\"\u003e\n    (* A curried function *)\n    let f x y = x + y\n\n    (* Function application *)\n    let result = f 10 (2 * 6)\n\n    (* Partial application *)\n    let g x = f x 2\n\n    (* We can re-bind variables *)\n    let x = 123\n    let x = string_of_int x\n\nRecursive functions are marked with the `rec` keyword.\n\n    let rec fact n = if n = 0\n             then 1\n             else n * fact (n - 1)\n\n\u003c/div\u003e\n\nHere's an example of a higher-order function \u0026 multiple local functions\n\u0026 an infix operator \u0026 an anonymous function \u0026 the main method is\nparametricly polymorphic.\n\n    let try_add (bop : 'a -\u003e 'a -\u003e 'a) (test : 'a -\u003e bool)\n            (default : 'a) (x : 'a) (y : 'a)\n       = let (/@/) x y = bop x y\n         (* Only select symbols can be used as infix operators *)\n         (* (/@/) x y  =  x /@/ y *)\n         and wrap a = if test a then a else default\n         in wrap x /@/ wrap y;;\n\n      699 = try_add (+) (fun a -\u003e a mod 3 = 0) (666) (~-1) 33;;\n      (* The anonymouse function uses ‘=’ as Boolean equality. *)\n\n      ~- 2 = ~- 2 mod 3;; (* /Remainder/ after dividing out 3s *)\n\n\n\u003ca id=\"orgd3de3b7\"\u003e\u003c/a\u003e\n\n# Booleans\n\nInequality is expressed with `\u003c\u003e`.\n\n    (* false, true, false, true, false, true, true, 1 *)\n    true = false , true || false, true \u0026\u0026 false, true \u003e= false\n    , 12 \u003c 2, \"abc\" \u003c= \"abd\", 1 \u003c\u003e 2\n    , if true then 1 else 2\n\n\n\u003ca id=\"org10d734c\"\u003e\u003c/a\u003e\n\n# Strings\n\nOCaml strings are not arrays, or lists, of characters as in C or Haskell.\n\n    \"string catenation\" = \"string \" ^ \"catenation\"\n\n    Printf.printf \"%d %s\" 1972 \"taxi\";;\n    let input = read_line ();;\n\n\n\u003ca id=\"org262bbec\"\u003e\u003c/a\u003e\n\n# Records\n\nRecords: Products with named, rather than positional, components.\n\n    type point2d = {x : float; y : float};;\n\n    (* Construction *)\n    let p = {y = 2.0; x = 3.4};;\n\n    (* Pattern matching for deconstruction *)\n    let {x = px; y = py} = p;;\n    let go {x = qx; y = qy} = qx +. qy;;\n\n    (* More tersely, using “field punning”: Variables must coincide with field names. *)\n    let erroenous ({xx; y} : point2d )= x +. y;;\n    let works {x; y} = 0.0;;\n\n    (* Or we can use dot notation *)\n    let go q = q.x +. q.y;;\n\n\n\u003ca id=\"org6608e6d\"\u003e\u003c/a\u003e\n\n# Variants and Pattern Matching\n\nVariant types: A unified way to combine different types into a single type;\neach case is distinuighed by a capitalised tag.\n\n    (* Constructors must start with a capital letter, like in Haskell *)\n    type 'a fancy_num =   Nothing | Boring of int | Fancy of 'a\n                | Point of point2d | Pair of 'a fancy_num * 'a fancy_num\n\n    let example = Pair (Fancy \"twenty\", Point {x = 1.2; y = 3.14})\n\nThe tags allow us to *extract* components of a variant value\nas well as to case against values by inspecting their tags.\nThis is *pattern matching*.\n\n    (* Destructuring a value *)\n    let Pair(head, _) = example;;\n\n    (* Guarded pattern matching, with in-line casing via ‘match’ *)\n    let rec sum acc = function\n      | Nothing -\u003e 0 + (match acc with true -\u003e 1 | false -\u003e 0)\n      | Fancy x when x \u003c= \"nine\" -\u003e 0\n      | (Fancy \"twenty\") as p -\u003e failwith \"Evil!\"\n      | Pair(l, r) -\u003e sum acc l + sum acc r\n      | _ -\u003e 2 (* Default case *)\n\n    let res = sum true example (* Exception: Failure \"Evil!\" *)\n\n    (* Type aliases can also be formed this way *)\n    type myints = int\n\nNote that we can give a pattern a name; above we mentioned `p`,\nbut did not use it.\n\n-   Repeated \u0026 non-exhaustive patterns trigger a warning; e.g., remove the default case above.\n\n-   You can pattern match on arrays too; e.g.,\n    `[| x ; y ; z|] -\u003e y`.\n\nThe above mechanisms apply to all variants \u0026#x2014;including tuples, lists, and options.\n\n\n\u003ca id=\"org67af557\"\u003e\u003c/a\u003e\n\n# Tuples and Lists\n\nTuples: Parentheses are optional, comma is the main operator.\n\n    let mytuple  : int * string * float = (3, \"three\", 3.0);;\n\n    (* Pattern matching \u0026 projection *)\n    let (woah0, woah1, woah2) = mytuple;;\n    let add_1and4 (w, x, y, z) = w + z;;\n    let that = fst (\"that\", false)\n\n    (* A singelton list of one tuple !!!!  *)\n    let zs = [ 1, \"two\", true ]\n\n    (* Lists:  type 'a list = [] | (::) of 'a * 'a list  *)\n    let xs = [1; 2; 3]\n    [1; 2; 3] = 1 :: 2 :: 3 :: [];; (* Syntactic sugar *)\n\n    (* List catenation *)\n    [1;2;4;6] = [1;2] @ [4;6];;\n\n    (* Pattern matching example; Only works on lists of length 3 *)\n    let go [x; y; z] = x + y + z;;\n    14 = go [2;5;7];;\n\n    (* Labelled arguments, using ‘~’, means position is irrelevant *)\n    [1; 2; 3] = List.map [\"a\", \"ab\", \"abc\"] ~f:String.length;;\n    [1; 2; 3] = List.map  ~f:String.length [\"a\", \"ab\", \"abc\"];;\n\n\\columnbreak\n\n\n\u003ca id=\"orgbe4f146\"\u003e\u003c/a\u003e\n\n# Options\n\nOption: Expressing whether a value is present or not.\n\n    (* type 'a option = None | Some of 'a *)\n\n    let divide x y : int option = if y = 0 then None else Some (x / y);;\n\n    let getInt ox = match ox with None -\u003e 0 | Some x -\u003e x;;\n    0 = getInt None;;\n    2 = getInt (Some 2);;\n\n\n\u003ca id=\"org8dae4ac\"\u003e\u003c/a\u003e\n\n# Imperative Programming \u0026#x2014;Sequencing \u0026 `main`\n\nWe may use begin/end or parentheses to group\nexpressions together.\n\n\u003cdiv class=\"parallel\"\u003e\n    (* Inline *)\n    let x = begin 1 * 2 end + (3 - 2);;\n\n    (* Parentheses *)\n    (  print_string \"a\"\n     ; () (* This is the unit value *)\n     ; 9\n    );;\n\n    (* Begin-end block *)\n    begin\n      print_string \"nice\";\n      \"bye\";\n      true;\n      10\n    end;;\n\n\u003c/div\u003e\n\nRemember: Single semicolon `;` is for sequencing whereas double `;;` is for termination.\n\nOCaml programs don't have a unique `main` function as in C, instead the entire file\nis evaluated sequentially at startup, which may contain arbitrary expressions not just functional declarations,\nand so in some sense the full codebase is one big `main` function.\n\n\n\u003ca id=\"orge48c00e\"\u003e\u003c/a\u003e\n\n# Imperative Programming \u0026#x2014;Arrays\n\nZero-indexed Arrays: Indexing with `.(i)` and update with `\u003c-`.\n\n    let nums : int array = [| 1; 2; 3 |];;\n    nums.(0) \u003c- 12;;\n\n    12 = nums.(0);;\n    [|12; 2; 3|] = nums;;\n\nWhat is the *type* of update, `\u003c-`? A function that returns the unit type!\n\u0026#x2014;see `myupdate` below.\n\n\n\u003ca id=\"orgbbe1203\"\u003e\u003c/a\u003e\n\n# Imperative Programming \u0026#x2014;Unit Type\n\nOperations whose use produces a side-effect return the `unit` type.\nThis’ akin to the role played by `void` in C.\nA *function* is a sequence of expressions; its *return value*\nis the value of the final expression \u0026#x2014;all other expressions\nare of unit type.\n\n\u003cdiv class=\"parallel\"\u003e\n    (* type unit = () *)\n    let ex : unit = ();;\n\n    let myupdate (arr : 'a array) (e : 'a)\n             (i : int) : unit\n      = arr.(i) \u003c- e;;\n\n    myupdate nums 33 1;;\n    [|12; 33; 3|] = nums;;\n\n    let my_io () = print_endline \"Hello!\" ;;\n\n    let const x y\n      = my_io();\n        y;\n        x;;\n\n    let res = const 1972 12;;\n\n\u003c/div\u003e\n\n\n\u003ca id=\"org186bdec\"\u003e\u003c/a\u003e\n\n# Imperative programming \u0026#x2014;Mutable records\n\nRecord fields are immutable by default, but can be declared mutable.\n\n    type running_sum = {mutable sum : int; mutable more : int};;\n\n    let create () = {sum = 0; more = 0};;\n\n    let update rs x =   rs.sum  \u003c- rs.sum + rs.more\n              ; rs.more \u003c- x;;\n\n    let  res = create ()\n    in   update res 12\n       ; {sum = 0; more = 12} = res ;;\n\n\n\u003ca id=\"org7589654\"\u003e\u003c/a\u003e\n\n# Imperative Programming \u0026#x2014;References\n\nReferences: Single mutable values; i.e., a record with a single mutable field named `contents`.\n\n    let x : int ref = {contents = 0}\n    in x.contents \u003c- x.contents + 1; {contents = 1} = x;;\n\nRefs come with a handful of convenience methods; here's their re-implementation:\n\n    (* Alias    *) type 'a ref  = {mutable contents : 'a};;\n    (* Creation *) let ref v    = {contents = v};;\n    (* Access   *) let (!) r    = r.contents;; (* “value of” *)\n    (* Update   *) let (:=) r e = r.contents \u003c- e;;\n\nNotice that `ref` is overloaded: As a type former and as a function forming values.\n\n    (* Summing the first 10 numbers *)\n    let  sum = ref 0\n    in   for i = 0 to 10 do sum := !sum + i done\n       ; 55 = !sum;;\n\n    true\n\n\\columnbreak\n\n\n\u003ca id=\"orgf9e076f\"\u003e\u003c/a\u003e\n\n# Modules\n\nOCaml files not only store \u0026 manage code, but also correspond to (second-class) ‘modules’,\nwhich act as boundaries that divide a program into conceptual units.\n\n-   At its simplest, a module is a collection of definitions that are stored\n    within a namespace.\n\n-   Implementation details of a module can be hidden by using an\n    *interface, module type, signature* \u0026#x2014;all are aliases.\n    -   `val` declarations specify values in a signature: `val ⟪identifier⟫ : ⟪type⟫`.\n    -   A type is *abstract* if its name is exposed in the interface but its definition is not: `type t`.\n        -   It is conventional to use `t` for the name of such types.\n    -   Including the type definition in the interface makes the type *concrete*.\n\n-   E.g., module names are derived, with capitalisation, automatically from file names.\n    An interface for `myfile.ml` to constrain exposed interface is placed in `myfile.mli`.\n\n    This is nearly how C header and implementation files work.\n\n-   Modules \u0026 signatures can be nested inside other modules.\n\nModules names always begin with a capital; their contents are accessed with\ndot notation. Here is the general syntax:\n\n    (* Module declaration *)\n    module ‘Name’ : ‘signature’ = struct ‘implementation’ end\n\n    (* Signature declaration *)\n    module type ‘Name’ = sig ‘sig_decls’ end\n\n    (* sig_decls are a space-separated sequence of “type” or “val : ‘name’ : ‘type’”\n    declarations. A “type” declaration with no “= ⋯” is an abstract type. *)\n\nWithout constructors `type` creates aliases, if we want to treat a type in two different\nways and have the compiler ensure we don't mess-up, we produce single-constructor new\ntypes:\n\n\u003cdiv class=\"parallel\"\u003e\n    type person  = P of string;;\n    type address = A of string;;\n\n    let jasim : person  = P \"jasim\";;\n    let home  : address = A \"the farm\";;\n\n    (* Type error *)\n    let this : person = home;;\n\n    (* If needed, we could make coercions *)\n    let person_to_string : person -\u003e string\n     = function P s -\u003e s\n\n    let address_of_string : string -\u003e address\n     = fun s -\u003e A s\n\n\u003c/div\u003e\n\nHowever, if the underlying type were the *same,* this repetition could be error-prone.\nInstead, we could use *generative modules*: Distinct types with the same underlying implementation.\nBeing ‘generative’ is akin to the `new` keyword in Java:\n  Each use of the `BasicImplementation` module below makes a new type.\n\n\u003cdiv class=\"parallel\"\u003e\n    module type EssentiallyString = sig\n      type t\n      val to_string : t -\u003e string\n      val from_string : string -\u003e t\n      val (=) : t -\u003e t -\u003e bool\n      end\n\n    module BasicImplementaion\n           : EssentiallyString = struct\n      type t = string\n      let to_string x = x\n      let from_string x = x\n      let (=) l r = String.(l = r)\n    end\n\n\u003c/div\u003e\n\nNote that `BasicImplemention` is just a namespace where, e.g., `t` is an alias for `string`.\n\n    (* Here we get to reuse the above, thereby avoiding repetition *)\n    module Person  : EssentiallyString = BasicImplementaion\n    module Address : EssentiallyString = BasicImplementaion\n\n    let jasim : Person.t  = Person.from_string \"jasim\";;\n    let home  : Address.t = Address.from_string \"the farmlands\";;\n\n    (* Type error: Expected a Person.t, but have a Address.t *)\n    let uhoh : Person.t = home;;\n\nNote that we could have placed the definitions of `EssentiallyString`\nand \\newline `BasicImplementaion` in-line for the `Person` and `Address` module\ndeclarations \u0026#x2014;without syntactic alterations\u0026#x2014; but that would have\ndefeated our purpose of avoiding repetition.\n\nWithout the type annotation, we could accidentally forget to implement\npart of the interface \u0026 OCaml would infer a different module type.\nUse the `module type of` operator to see what was inferred.\n\n    module ErroneousImplementation = struct\n      type t = string let (=) l r = String.(l = r)\n    end\n\n    module type S = (module type of ErroneousImplementation)\n    (* module type S = sig type t = string val ( = ) : 'a -\u003e 'a -\u003e bool end *)\n\nMany *equivalent* ways to use module contents \u0026#x2014;the third is for small expressions.\n\n-   Note the dot!\n\n    let qasim = Person.(from_string \"jasim\")\n    in   (let open Person in qasim = jasim)\n       , Person.(=) qasim jasim\n       , Person.(from_string \"jasim\" = jasim)\n       (* Rebind module name to a shorter name *)\n       , let module P = Person in P.(qasim = jasim)\n    ;;\n\nWhile opening a module [type] affects the environment used to search for identifiers,\n*including* a module is a way of adding new identifiers to a module [type] proper\n\u0026#x2014;it is a copy-paste of constituents.\nFor example, we could re-organise `EssentialyString` into a hierarchy:\n\n    module type Type = sig type t end\n\n    module type Relation = sig include Type val (=) : t -\u003e t -\u003e bool end\n    (* module type Relation = sig type t val ( = ) : t -\u003e t -\u003e bool end *)\n\n    module type PingPong = sig\n      include Type val from_string : string -\u003e t val to_string : t -\u003e string end\n\nThis allows us to form *extensions* to modules, akin to C#:\nTo extend, say, the `List` module with a new function `f` so that\n`List.f` is valid, we make and open `module List = struct let f = ⋯ include List`.\nIf we wanted to *override* an existing `f`, we put its definition after the include.\n\nThe interface would be `sig val f : ⋯ include (module type of List) end`.\n\nWhen we have multiple declarations of a type or we have type that is too abstract to be\nof use, expect to see:\n`Error: This expression has type 𝓉 but an expression was expected of type M.t`; instead maybe use `M.t with type t = 𝓉`, where:\n\n    (* “Constraint Sharing”: Declaration of t stays as an alias. *)\n       sig type t val ⋯ end with type t = imp\n    ≈  sig type t = imp val ⋯ end\n\n    (* “Destructive Substitution”: Declaration of t is gone. *)\n       sig type t val ⋯t⋯ end with type t := imp\n    ≈  sig val ⋯imp⋯ end\n\nWe may now continue our `EssentiallyString` hierarchy:\n\n    module type IntRelation = sig include Relation with type t := int end\n    (* Desugars: module type IntRelation = sig val ( = ) : int -\u003e int -\u003e bool end *)\n    module type EssentiallyStr = sig include Type include Relation with type t := t end\n\n**Warning!**\nThe order of constructor declarations for a concrete type variant must be the\nsame in the implementation as in the interface, likewise for record fields and\nfunction arguments.\n\n\n\u003ca id=\"orgacb6c97\"\u003e\u003c/a\u003e\n\n# Functors\n\nFunctors are, roughly speaking, functions from modules to modules.\n\u0026#x2014; There's no “modules to module types” thing, [instead](https://stackoverflow.com/a/54783553/3550444) we return\na module that contains a module type ;-) \u0026#x2014;\n\n\\room\nFunctors provide the same abstraction features as functions do but also\nallow the implementation of one module to *vary* depending on another module.\nIn contrast to functions, functors require explicit type annotation\n\u0026#x2014;otherwise how would we know what constituents the input module contains\u0026#x2014;\nand their arguments *must* be enclosed in parentheses.\n\nIn a sense, these are parameterised modules \u0026#x2014;as in Agda\u0026#x2014; and that is how\nthey may be treated syntactically in OCaml:\n\n    (* Example functor that takes a namespace having ‘x’\n       and yields a namspace with ‘x’ incremented. *)\n\n      module type OneInt = sig val x : int end;;\n      module IncrementFunctor (M : OneInt) : OneInt = struct let x = M.x + 1 end;;\n\n      module Three : OneInt = struct let x = 3 end;;\n      module Four  : OneInt = IncrementFunctor(Three);;\n\n      Four.x = Three.x + 1;;\n\nA functor may be applied to **any** module that satisfies the functor's input interface:\n\n    module Point = struct let x = 0 let y = 1 end;;\n    module One = IncrementFunctor(Point);;\n    One.x = Point.x + 1;;\n\n\n\u003ca id=\"org1f3bead\"\u003e\u003c/a\u003e\n\n# First-Class Modules\n\nModules can contain types \u0026 values, but ordinary values can't contain modules or\nmodule types. In order to define variables whose value is a module, or a function\nthat takes a module as an argument, OCaml provides *first-class modules* which are\nordinary values that can be created from and converted back to regular modules.\n\nA first-class module is created by packaging up a module with a signature that\nit satisfies by using the `module` keyword:\n\n    let three    : (module OneInt) = (module Three : OneInt);;\n    let three'   = (module Three);; (* Error: Signature couldn't be inferred *)\n    let three''  : (module OneInt) = (module Three);;\n    let three''' = (module Three : OneInt);; (* Most terse ^_^ *)\n\n    (* Lists are homogeneous, whence latters' type inferred from formers'  *)\n    let list_of_modules = [three; (module Three); (module Four)];;\n\nDot notation only works for records and modules, so we access contents of a\nfirst-class module by turning it into an ordinary module with `val`:\n\n    let x : int = let module M = (val three : OneInt) in M.x;;\n    let x : int = (val three : OneInt).x;; (* Error: Invalid syntax. *)\n\n**Warning!** The parentheses for these `module, val` keywords are important!\n\nRule of thumb: Use the forms `(module M : T)` and `(val M : T)` always.\n\nWe can create ordinary functions which consume and create first-class modules.\n\n    let unpack (m : (module OneInt)) : int = let module M = (val m) in M.x;;\n    let pack (n : int) : (module OneInt) = (module struct let x = n end);;\n\n    3 = unpack three;;\n    3 = unpack (pack 3);;\n    pack 3 = three;; (* Woah! Equality of modules! *)\n\n    (* “Module pattern matching” *)\n    (* unpack' : (module OneInt) -\u003e int *)\n    let unpack' (module M : OneInt) = M.x;;\n\n    true\n\n\\columnbreak\n\n\n\u003ca id=\"org02ce931\"\u003e\u003c/a\u003e\n\n# *Locally* Abstract Types \u0026 ‘[un]bundling’\n\nType variables are generally implicit, but we can treat them as abstract types\nin a function body yet still not pass them in explicitly at use-sites.\n\n    (* Where did the 'a come from? *)\n    let wrap (x : 'a) : 'a list = [x];;\n\n    (* Let's explicitly declare it! *)\n    let wrap' (type a) (x : a) : a list = [x];;\n\n    (* Usage doesn't change. *)\n    wrap 1 = wrap' 1\n\nOne use is to connect the abstract types of a first-class module with other types\nwe're working with \u0026#x2014;by using constraint sharing.\n*That is, we ‘unbundle’ the type from ‘inside’ the module to its ‘type’.*\n**This is a prime reason to use first-class modules!**\n\nHere's an example where we approximate C#'s `default` keyword:\n\n    module type Pointed = sig type t val point : t end;;\n\n    (* Error: The hidden type of M is exposed!\n       “The type constructor M.t would escape its scope.”\n       “here : (M:Pointed) → M.t” *)\n    let default (module M : Pointed) = M.point;;\n\n    (* default : (module Pointed with type t = 'a) -\u003e 'a *)\n    let default (type a) (module M : Pointed with type t = a) = M.point;;\n\n    module Nat : Pointed with type t = int = struct type t = int let point = 0 end;;\n    (* module Nat = struct type t = int let point = 0 end;; *)\n\n    (* ‘default’ works on first-class modules *)\n    0 = default(module Nat)\n\n*Conversely, this allows us to ‘bundle’ up data to form a module!*\n\n    (* make_pointed : 'a -\u003e (module Pointed with type t = 'a) *)\n    let make_pointed (type a) (x : a) : (module Pointed with type t = a)\n      = (module struct type t = a let point = x end)\n\n\n\n\u003ca id=\"org2064485\"\u003e\u003c/a\u003e\n\n# Metaprogramming with [MetaOCaml](http://okmij.org/ftp/ML/MetaOCaml.html)\n\nQuasi-quote expressions with ‘brackets’ `.\u003c expr \u003e.`\n*to delay their execution*\nand splice quoted items into such an expression with ‘escape’ `.~expr.`\nFinally, code can be ‘run’ with `Runcode.run expr`.\n\n**Warning!** You must use the `metaocaml` command rather than the `ocaml` command.\n\n    open Runcode;;\n\n    (* Addition is not performed right now, but transformed into ‘code’ *)\n    let x : int code = .\u003c1 + 2\u003e.;; (* .\u003c1 + 2\u003e. *)\n\n    (* Actually execute the addition *)\n    let y : int = run x;;\n\n    (* Example using escape *)\n    let z : int code = .\u003c let res = .~x in res + res \u003e.;;\n    6 = run z;;\n\n    (* A more complicated example *)\n\n    (* Desugars using a fresh name: .\u003cfun x_4 -\u003e 2 * x_4\u003e. *)\n    let ff = let c = 2 in .\u003c fun x -\u003e c * x \u003e.;;\n    let six = .\u003c .~ff 3 \u003e.;; (* .\u003c(fun x_14 -\u003e 2 * x_14) 3\u003e. *)\n\nThe traditional ‘staging of the power function’ example\ncan be found [here](http://ocamllabs.io/iocamljs/staging.html) \u0026#x2014;as a Jupyter Notebook.\n\nFor more, see [A Gentle Introduction to Multi-stage Programming](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.438.6924\u0026rep=rep1\u0026type=pdf)\n\n-   The deprecated `!.` is replaced with `Runcode.run`.\n-   A Haskell rendition can be found [here](https://github.com/alhassy/multistage-programming-taha).\n\n\\columnbreak\n\n\n\u003ca id=\"orgdc9edf1\"\u003e\u003c/a\u003e\n\n# Reads\n\n-   [X] [Learn *x* in *y* minutes, where *x = OCaml* ](https://learnxinyminutes.com/docs/ocaml/)\n-   [X] [Try OCaml, online](https://try.ocamlpro.com/)\n-   [X] [Real World OCaml](https://realworldocaml.org/)\n-   [ ] [OCaml meta tutorial](https://ocaml.org/learn/tutorials) \u0026#x2014;including [99 Problems](https://ocaml.org/learn/tutorials/99problems.html)\n-   [ ] [Unix system programming in OCaml](http://ocaml.github.io/ocamlunix/?ref=hackr.io)\n","funding_links":[],"categories":["Others"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falhassy%2FOCamlCheatSheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falhassy%2FOCamlCheatSheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falhassy%2FOCamlCheatSheet/lists"}