Created
November 21, 2017 21:18
-
-
Save dudelson/78ff45b20c0ea168613e26e125e3a9ae to your computer and use it in GitHub Desktop.
Illustration of functors in ocaml and comparison to functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* Basic demonstration of how to create and use functors, | |
* as well as how they parallel functions *) | |
(* Here are the two (equivalent) ways to define a function *) | |
let f x = x + 1 | |
let g = fun x -> x + 1 | |
(* The functor has the same two syntaxes as the function, except whereas a | |
* function takes one or more 'expressions' (each of which has a 'type') and | |
* outputs a 'value' ('values' are just the subset of 'expressions' which cannot | |
* be evaluated further, thus they also have 'types'), a functor take one or more | |
* 'module-expressions' (each of which has a 'module-type') and outputs a | |
* 'module-expression' (with a 'module-type'). 'module-expressions' are also | |
* called 'structures' and 'module-types' are also called 'signatures'. | |
*) | |
(* Unlike functions, ocaml cannot infer the types for parameters to a functor, | |
* so they always need to be explicitly declared. AFAIK at the time of writing, | |
* there are no "built-in" module types provided by the ocaml core language, so | |
* we will create our own simple module type *) | |
module type X = sig | |
val x : int | |
end | |
(* Here are the two (equivalent) ways to define a functor. Note how they're exactly | |
* the same syntactically as the function definitions above, except the signatures | |
* of the functor parameters always need to be made explicit. The signature of | |
* the return structure, however, does not need to be made explicit; note how it | |
* is present in the first definition and omitted in the second. *) | |
module IncX (M : X) : X = struct | |
let x = M.x + 1 | |
end | |
module IncX2 = functor (M : X) -> struct | |
let x = M.x + 1 | |
end | |
(* Here we use the functors we defined above to create some structures *) | |
module A = struct let x = 0 end | |
module B = IncX(A) | |
module C = IncX(B) | |
module D = IncX2(A) | |
module E = IncX2(D) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment