Created
August 4, 2015 16:33
-
-
Save tel/d0b8a7ace2bc0bbf3646 to your computer and use it in GitHub Desktop.
Sums in Javascript
This file contains hidden or 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
/* | |
"Concrete" sums are by default open. They are values of the form | |
{ variant: String, params: {[String]: *} } | |
*/ | |
/** | |
* A very general (named) matcher for concrete sums. | |
* | |
* @invariant x : object | |
* @invariant x.variant : string | |
* @invariant x.params is a dictionary | |
* @invariant pat[x.variant] is callable | |
*/ | |
function match(x, pat) { return pat[x.variant](x.params); } | |
/** | |
* Church encoding a concrete sum. | |
* @type {Sum -> Pattern[Sum] r -> r} | |
*/ | |
function church(x) { return pat => match(x, pat); } | |
/* | |
Church encoding trades sums for products by encoding a sum as exactly its | |
matching behavior. This is a faithful encoding in a typed language. | |
We can also create "Church sums" directly by encoding a fragment of the | |
matching algorithm. | |
*/ | |
function Just(a) { return pat => pat.Just({value: a}); } | |
function Nothing() { return pat => pat.Nothing({}); } | |
function matchChurch(pat) { return sum => sum(pat); } | |
/* | |
It's worth noting that in OO-mythos the Church encoded sum has been around | |
for a long time under the name "visitor pattern". In this case, sums are types | |
which accept visitation methods only and patterns are the visitors. | |
*/ | |
/* | |
While the above system provides the explicitness and power of a normal typed sum system | |
it obviously is a bit weird for lacking types. In order for the above to work we must have | |
that patterns always "cover" the sums that they're matched against. This induces a | |
structural subtyping system on "open" sums which follows exactly from the "duck typing" | |
structural subtyping system on the regular Javascript objects which implement patterns. | |
Sum : Pattern -> Type | |
Sum pat = forall r . pat r -> r | |
Maybe a = Sum { Nothing: () -> r, Just: a -> r } | |
= { Nothing: () -> r, Just: a -> r } -> r | |
This expanded dynamics can be useful | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment