Last active
January 4, 2022 22:41
-
-
Save ForbesLindesay/5392337 to your computer and use it in GitHub Desktop.
Revisions
-
ForbesLindesay revised this gist
Apr 22, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -48,7 +48,7 @@ If an entity (call it `A`) implements a method `map` then when it is passed one `map` must also obey the following two rules: 1. `A.map(function (a) { return a; })` is equivalent to `A` ( _identity_ ) 2. `A.map(function (x) { return f(g(x)); })` is equivalent to `A.map(g).map(f)` ( _composition_ ) A practical example of how `map` might be implemented is the array, which calls map for each element in the array and returns a new array that is an array of the results of the function, e.g.: -
ForbesLindesay revised this gist
Apr 20, 2013 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -32,14 +32,14 @@ If an entity (call it `A`) implements a method `concat` then when it is passed o ( _an entity that implements `concat` is also known as a 'semigroup' in functional programming_ ) ### A.constructor.empty() Any entity that implements `empty` must also implement `concat`. `A.constructor.empty()` must return an entity of the same class as `A` which obeys the following two rules. 1. `A` is equivalent to `A.concat(A.constructor.empty())` ( _right identity_ ) 2. `A` is equivalent to `A.constructor.empty().concat(A)` ( _left identity_ ) ( _an entity that implements `empty` is also known as a 'monoid' in functional programming_ ) ### A.map(fn) -
ForbesLindesay revised this gist
Apr 16, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -77,7 +77,7 @@ It must also obey the rule: Any entity that implements `of` must also implement `chain`. `A.constructor.of(B)` must return an entity of the same class as `A` which obeys the following three rules. 1. If `f` is a function that returns an entity of class `A`, then `A.of(b).chain(f)` is equivalent to `f(b)` ( _left identity_ ) 2. `A.chain(A.constructor.of)` is equivalent to `A` ( _right identity_ ) 3. Nothing about the contents of `A` may be checked, it is to be treated as an opaque value ( _an entity that implements `of` is also known as a 'monad' in functional programming_ ) -
ForbesLindesay revised this gist
Apr 16, 2013 . 1 changed file with 11 additions and 11 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -28,27 +28,27 @@ Examples: If an entity (call it `A`) implements a method `concat` then when it is passed one argument that is of the same class as `A` it must: 1. return a value with the same type as `A` (the object on which the method was called). 2. It must be associative. That is to say `a.concat(b).concat(c)` must be equivalent to `a.concat(b.concat(c))` ( _associativity_ ) ( _an entity that implements `concat` is also known as a 'semigroup' in functional programming_ ) ### A.constructor.zero() Any entity that implements `zero` must also implement `concat`. `A.constructor.zero()` must return an entity of the same class as `A` which obeys the following two rules. 1. `A` is equivalent to `A.concat(A.constructor.zero())` ( _right identity_ ) 2. `A` is equivalent to `A.constructor.zero().concat(A)` ( _left identity_ ) ( _an entity that implements `zero` is also known as a 'monoid' in functional programming_ ) ### A.map(fn) If an entity (call it `A`) implements a method `map` then when it is passed one argument that is a function, map must return an entity of the same class as `A`. `map` must also obey the following two rules: 1. `A.map(function (a) { return a; })` is equivalent to `A` ( _identity_ ) 2. `A.map(function (x) { return f(g(x)); })` is equivalent to `u.map(g).map(f)` ( _composition_ ) A practical example of how `map` might be implemented is the array, which calls map for each element in the array and returns a new array that is an array of the results of the function, e.g.: @@ -62,22 +62,22 @@ var res = arr.map(square); `res` would then be `[1, 4, 9, 16]` ( _an entity that implements `map` is also known as a 'functor' in functional programming_ ) ### A.chain(fn) If an entity (call it `A`) implements a method `chain` then when it is passed one argument that is a function and that function returns an entity of the same class as `A`, chain must return an entity of the same class as `A`. It must also obey the rule: 1. `A.chain(f).chain(g)` is equivalent to `A.chain(function (x) { return f(x).chain(g); })` ( _associativity_ ) ### A.constructor.of(B) Any entity that implements `of` must also implement `chain`. `A.constructor.of(B)` must return an entity of the same class as `A` which obeys the following three rules. 1. If `f` is a function that returns an entity of class `A`, then `A.of(b).chain(f)` is equivalent to `f(b)` ( _left identity_ ) 2. `A.chain(A.constructor.of)` is equivalent to `A` (_right identity_) 3. Nothing about the contents of `A` may be checked, it is to be treated as an opaque value ( _an entity that implements `of` is also known as a 'monad' in functional programming_ ) -
ForbesLindesay revised this gist
Apr 16, 2013 . 1 changed file with 18 additions and 9 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -28,23 +28,27 @@ Examples: If an entity (call it `A`) implements a method `concat` then when it is passed one argument that is of the same class as `A` it must: 1. return a value with the same type as `A` (the object on which the method was called). 2. It must be associative. That is to say `a.concat(b).concat(c)` must be equivalent to `a.concat(b.concat(c))` (_associativity_) (_an entity that implements `concat` is also known as a 'semigroup' in functional programming_) ### A.constructor.zero() Any entity that implements `zero` must also implement `concat`. `A.constructor.zero()` must return an entity of the same class as `A` which obeys the following two rules. 1. `A` is equivalent to `A.concat(A.constructor.zero())` (_right identity_) 2. `A` is equivalent to `A.constructor.zero().concat(A)` (_left identity_) (_an entity that implements `zero` is also known as a 'monoid' in functional programming_) ### A.map(fn) If an entity (call it `A`) implements a method `map` then when it is passed one argument that is a function, map must return an entity of the same class as `A`. `map` must also obey the following two rules: 1. `A.map(function (a) { return a; })` is equivalent to `A` (_identity_) 2. `A.map(function (x) { return f(g(x)); })` is equivalent to `u.map(g).map(f)` (_composition_) A practical example of how `map` might be implemented is the array, which calls map for each element in the array and returns a new array that is an array of the results of the function, e.g.: @@ -58,17 +62,22 @@ var res = arr.map(square); `res` would then be `[1, 4, 9, 16]` (_an entity that implements `map` is also known as a 'functor' in functional programming_) ### A.chain(fn) If an entity (call it `A`) implements a method `chain` then when it is passed one argument that is a function and that function returns an entity of the same class as `A`, chain must return an entity of the same class as `A`. It must also obey the rule: 1. `A.chain(f).chain(g)` is equivalent to `A.chain(function (x) { return f(x).chain(g); })` (_associativity_) ### A.constructor.of(B) Any entity that implements `of` must also implement `chain`. `A.constructor.of(B)` must return an entity of the same class as `A` which obeys the following three rules. 1. If `f` is a function that returns an entity of class `A`, then `A.of(b).chain(f)` is equivalent to `f(b)` (_left identity_) 2. `A.chain(A.constructor.of)` is equivalent to `A` (_right identity_) 3. Nothing about the contents of `A` may be checked, it is to be treated as an opaque value (_an entity that implements `of` is also known as a 'monad' in functional programming_) -
ForbesLindesay revised this gist
Apr 16, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -6,7 +6,7 @@ This project specifies the behavior of a number of methods that may optionally b ## Definitions For the purposes of this, spec, an "entity" is an object that has an `[[equivalent]]` operation (see bellow) and may implement some or all of the other methods. A "value" is any JavaScript value, this includes entities. -
ForbesLindesay revised this gist
Apr 16, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ (aka "Algebraic JavaScript Specification") This project specifies the behavior of a number of methods that may optionally be added to any object. The motivation behind this is to encourage greater code reuse. You can create functions that just rely on objects having implementations of the methods below, and in doing so you can make them work with a wide variety of different, but related data structures. ## Definitions -
ForbesLindesay revised this gist
Apr 16, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -66,7 +66,7 @@ It must also obey the rule: 1. `A.chain(f).chain(g)` is equivalent to `A.chain(function (x) { return f(x).chain(g); })` ### A.constructor.of(B) Any entity that implements `of` must also implement `chain`. `A.constructor.of(B)` must return an entity of the same class as `A` which obeys the following two rules. -
ForbesLindesay revised this gist
Apr 16, 2013 . 1 changed file with 9 additions and 9 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -27,24 +27,24 @@ Examples: If an entity (call it `A`) implements a method `concat` then when it is passed one argument that is of the same class as `A` it must: 1. return a value with the same type as `A` (the object on which the method was called). 2. It must be associative. That is to say `a.concat(b).concat(c)` must be equivalent to `a.concat(b.concat(c))` ### A.constructor.zero() Any entity that implements `zero` must also implement `concat`. `A.constructor.zero()` must return an entity of the same class as `A` which obeys the following two rules. 1. `A` is equivalent to `A.concat(A.constructor.zero())` 2. `A` is equivalent to `A.constructor.zero().concat(A)` ### A.map(fn) If an entity (call it `A`) implements a method `map` then when it is passed one argument that is a function, map must return an entity of the same class as `A`. `map` must also obey the following two rules: 1. `A.map(function (a) { return a; })` is equivalent to `A` 2. `A.map(function (x) { return f(g(x)); })` is equivalent to `u.map(g).map(f)` A practical example of how `map` might be implemented is the array, which calls map for each element in the array and returns a new array that is an array of the results of the function, e.g.: @@ -64,11 +64,11 @@ If an entity (call it `A`) implements a method `chain` then when it is passed on It must also obey the rule: 1. `A.chain(f).chain(g)` is equivalent to `A.chain(function (x) { return f(x).chain(g); })` ### `A.constructor.of(B)` Any entity that implements `of` must also implement `chain`. `A.constructor.of(B)` must return an entity of the same class as `A` which obeys the following two rules. 1. If `f` is a function that returns an entity of class `A`, then `A.of(b).chain(f)` is equivalent to `f(b)` 2. `A.chain(A.constructor.of)` is equivalent to `A` -
ForbesLindesay revised this gist
Apr 16, 2013 . 1 changed file with 15 additions and 9 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -6,33 +6,38 @@ This project specifies the behavior of a number of methods that may optionally b ## Definitions For the purposes of this, spec, an "entity" is a method that has an `[[equivalent]]` operation (see bellow) and may implement some or all of the other methods. A "value" is any JavaScript value, this includes entities. ## [[equivalent]] [[equivalent]] is an imaginary function that takes two arguments and returns `true` or `false`. It should return `true` iff the two objects could be swapped and no program would be able to tell the difference other than by checking the exact object references. Examples: - Two numbers are equivalent if they are equal - Two strings are equivalent if they are equal - Two arrays are equivalent if they contain equivalent items in the same order - Two functions (that have no side effects) are equivalent if they return equivalent outputs for equivalent inputs. ## Methods ### A.concat(B) If an entity (call it `A`) implements a method `concat` then when it is passed one argument that is of the same class as `A` it must: 1. return a value with the same type as `A` (the object on which the method was called). 2. It must be associative. That is to say `a.concat(b).concat(c)` must be equivalent to `a.concat(b.concat(c))` ### A.constructor.zero() Any entity that implements `zero` must also implement `concat`. `A.constructor.zero()` must return an entity of the same class as `A` which obeys the following two rules. `A` is equivalent to `A.concat(A.constructor.zero())` `A` is equivalent to `A.constructor.zero().concat(A)` ### A.map(fn) If an entity (call it `A`) implements a method `map` then when it is passed one argument that is a function, map must return an entity of the same class as `A`. @@ -49,9 +54,10 @@ function square(a) { return a * a; } var res = arr.map(square); ``` `res` would then be `[1, 4, 9, 16]` ### A.chain(fn) If an entity (call it `A`) implements a method `chain` then when it is passed one argument that is a function and that function returns an entity of the same class as `A`, chain must return an entity of the same class as `A`. -
ForbesLindesay created this gist
Apr 16, 2013 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,68 @@ # Real World Specification (aka "Algebraic JavaScript Specification") This project specifies the behavior of a number of methods that may optionally be added to any object. The motivation behind this is to encourage greater code use. You can create functions that just rely on objects having implementations of the methods below, and in doing so you can make them work with a wide variety of different, but related data structures. ## Definitions For the purposes of this, spec, an "entity" is a method that implements `.equivalence` and may implement some or all of the other methods. A "value" is any JavaScript value, this includes entities. ## Methods ### `A.equivalent(B)` All entities must implement equivallence. It must return `true` or `false` when given an entity of the same class. e.g. numbers would be equivalent if they are equal. Arrays would be equivalent if they are of the same length and contain equivalent elements in the same order. ### `A.concat(B)` If an entity (call it `A`) implements a method `concat` then when it is passed one argument that is of the same class as `A` it must: 1. return a value with the same type as `A` (the object on which the method was called). 2. It must be associative. That is to say `a.concat(b).concat(c)` must be equivalent to `a.concat(b.concat(c))` ### `A.constructor.zero()` Any entity that implements `zero` must also implement `concat`. `A.constructor.zero()` must return an entity of the same class as `A` which obeys the following two rules. `A` is equivalent to `A.concat(A.constructor.zero())` `A` is equivalent to `A.constructor.zero().concat(A)` ### `A.map(fn)` If an entity (call it `A`) implements a method `map` then when it is passed one argument that is a function, map must return an entity of the same class as `A`. `map` must also obey the following two rules: `A.map(function (a) { return a; })` is equivalent to `A` `A.map(function (x) { return f(g(x)); })` is equivalent to `u.map(g).map(f)` A practical example of how `map` might be implemented is the array, which calls map for each element in the array and returns a new array that is an array of the results of the function, e.g.: ```js var arr = [1, 2, 3, 4]; function square(a) { return a * a; } var res = arr.map(square); assert(res.equivalent([1, 3, 9, 16])); ``` ### A.chain(fn) If an entity (call it `A`) implements a method `chain` then when it is passed one argument that is a function and that function returns an entity of the same class as `A`, chain must return an entity of the same class as `A`. It must also obey the rule: `A.chain(f).chain(g)` is equivalent to `A.chain(function (x) { return f(x).chain(g); })` ### `A.constructor.of(B)` Any entity that implements `of` must also implement `chain`. `A.constructor.of(B)` must return an entity of the same class as `A` which obeys the following two rules. If `f` is a function that returns an entity of class `A`, then `A.of(b).chain(f)` is equivalent to `f(b)` `A.chain(A.constructor.of)` is equivalent to `A`