Merge pull request #37 from noplanman/proofing

In-depth proofreading and correcting
This commit is contained in:
hemanth.hm 2016-06-01 14:57:09 +05:30
commit 48eddbbc86

View file

@ -13,10 +13,11 @@
const sum = (a, b) => a + b; const sum = (a, b) => a + b;
const arity = sum.length; const arity = sum.length;
console.log(arity); console.log(arity); // 2
// => 2
// The arity of sum is 2 // The arity of sum is 2
``` ```
--- ---
## Higher-Order Functions (HOF) ## Higher-Order Functions (HOF)
@ -26,7 +27,7 @@ console.log(arity);
```js ```js
const filter = (pred, xs) => { const filter = (pred, xs) => {
const result = []; const result = [];
for (var idx = 0; idx < xs.length; idx += 1) { for (var idx = 0; idx < xs.length; idx++) {
if (pred(xs[idx])) { if (pred(xs[idx])) {
result.push(xs[idx]); result.push(xs[idx]);
} }
@ -40,7 +41,7 @@ const is = type => x => Object(x) instanceof type;
``` ```
```js ```js
filter(is(Number), [0, '1', 2, null]); //=> [0, 2] filter(is(Number), [0, '1', 2, null]); // [0, 2]
``` ```
## Partial Application ## Partial Application
@ -55,7 +56,7 @@ let sum = (a, b) => a + b;
let partial = sum.bind(null, 40); let partial = sum.bind(null, 40);
// Invoking it with `b` // Invoking it with `b`
partial(2); //=> 42 partial(2); // 42
``` ```
--- ---
@ -71,6 +72,7 @@ let curriedSum = (a) => (b) => a + b;
curriedSum(40)(2) // 42. curriedSum(40)(2) // 42.
``` ```
--- ---
## Composition ## Composition
@ -84,7 +86,6 @@ It allows you to combine functions that accept and return a single value.
const compose = (f, g) => a => f(g(a)) // Definition const compose = (f, g) => a => f(g(a)) // Definition
const floorAndToString = compose((val) => val.toString(), Math.floor) // Usage const floorAndToString = compose((val) => val.toString(), Math.floor) // Usage
floorAndToString(121.212121) // "121" floorAndToString(121.212121) // "121"
``` ```
--- ---
@ -97,9 +98,9 @@ input values, without any side effects.
```js ```js
let greet = "yo"; let greet = "yo";
greet.toUpperCase(); // YO; greet.toUpperCase(); // "YO"
greet // yo; greet // "yo"
``` ```
As opposed to: As opposed to:
@ -121,16 +122,21 @@ numbers // []
```js ```js
console.log("IO is a side effect!"); console.log("IO is a side effect!");
``` ```
--- ---
## Idempotency ## Idempotency
> A function is said to be idempotent if it has no side-effects on multiple > A function is said to be idempotent if it has no side-effects on multiple
executions with the the same input parameters. executions with the same input parameters.
`f(f(x)) = f(x)` ```js
f(f(x)) = f(x)
```
`Math.abs(Math.abs(10))` ```js
Math.abs(Math.abs(10))
```
--- ---
@ -168,7 +174,7 @@ Points-free function definitions look just like normal assignments without `func
## Categories ## Categories
> Objects with associated functions that adhere certain rules. E.g. [monoid](#monoid) > Objects with associated functions that adhere to certain rules. E.g. [Monoid](#monoid)
--- ---
@ -181,6 +187,7 @@ Points-free function definitions look just like normal assignments without `func
Object.freeze({name: 'John', age: 30}) // The `freeze` function enforces immutability. Object.freeze({name: 'John', age: 30}) // The `freeze` function enforces immutability.
(a) => a (a) => a
``` ```
Note that value-containing structures such as [Functor](#functor), [Monad](#monad) etc. are themselves values. This means, among other things, that they can be nested within each other. Note that value-containing structures such as [Functor](#functor), [Monad](#monad) etc. are themselves values. This means, among other things, that they can be nested within each other.
--- ---
@ -188,26 +195,29 @@ Note that value-containing structures such as [Functor](#functor), [Monad](#mona
## Constant ## Constant
> An immutable reference to a value. Not to be confused with `Variable` - a reference to a value which can at any point be updated to point to a different value. > An immutable reference to a value. Not to be confused with `Variable` - a reference to a value which can at any point be updated to point to a different value.
```js ```js
const five = 5 const five = 5
const john = {name: 'John', age: 30} const john = {name: 'John', age: 30}
``` ```
Constants are referentially transparent. That is, they can be replaced with the values that they represent without affecting the result. Constants are referentially transparent. That is, they can be replaced with the values that they represent without affecting the result.
In other words with the above two constants the expression: In other words with the above two constants the expression:
```js ```js
john.age + five === ({name: 'John', age: 30}).age + (5) john.age + five === ({name: 'John', age: 30}).age + (5)
``` ```
Should always return `true`. Should always return `true`.
--- ---
## Functor ## Functor
> An object with a `map` function that adhere to certains rules. `Map` runs a function on values in an object and returns a new object. > An object with a `map` function that adheres to certains rules. `map` runs a function on values in an object and returns a new object.
Simplest functor in javascript is an `Array` Simplest functor in javascript is an `Array`:
```js ```js
[2, 3, 4].map(n => n * 2); // [4, 6, 8] [2, 3, 4].map(n => n * 2); // [4, 6, 8]
@ -226,11 +236,13 @@ func.map(x => f(g(x))) == func.map(g).map(f)
``` ```
We can now see that `Array` is a functor because it adheres to the functor rules! We can now see that `Array` is a functor because it adheres to the functor rules!
```js ```js
[1, 2, 3].map(x => x); // = [1, 2, 3] [1, 2, 3].map(x => x); // = [1, 2, 3]
``` ```
and and
```js ```js
let f = x => x + 1; let f = x => x + 1;
let g = x => x * 2; let g = x => x * 2;
@ -238,12 +250,14 @@ let g = x => x * 2;
[1, 2, 3].map(x => f(g(x))); // = [3, 5, 7] [1, 2, 3].map(x => f(g(x))); // = [3, 5, 7]
[1, 2, 3].map(g).map(f); // = [3, 5, 7] [1, 2, 3].map(g).map(f); // = [3, 5, 7]
``` ```
--- ---
## Pointed Functor ## Pointed Functor
> A functor with an `of` method. `Of` puts _any_ single value into a functor. > A functor with an `of` method. `of` puts _any_ single value into a functor.
Array implementation:
Array Implementation:
```js ```js
Array.prototype.of = (v) => [v]; Array.prototype.of = (v) => [v];
@ -261,8 +275,10 @@ Map is the same as a lift over a one-argument function:
```js ```js
lift(n => n * 2)([2, 3, 4]); // [4, 6, 8] lift(n => n * 2)([2, 3, 4]); // [4, 6, 8]
``` ```
Unlike map lift can be used to combine values from multiple arrays: Unlike map lift can be used to combine values from multiple arrays:
```
```js
lift((a, b) => a * b)([1, 2], [3]); // [3, 6] lift((a, b) => a * b)([1, 2], [3]); // [3, 6]
``` ```
@ -301,10 +317,12 @@ let rand = function*() {
} }
} }
``` ```
```js ```js
let randIter = rand(); let randIter = rand();
randIter.next(); // Each exectuion gives a random value, expression is evaluated on need. randIter.next(); // Each execution gives a random value, expression is evaluated on need.
``` ```
--- ---
## Monoid ## Monoid
@ -342,14 +360,14 @@ The identity value is empty array `[]`
```js ```js
[1, 2].concat([]); // [1, 2] [1, 2].concat([]); // [1, 2]
``` ```
Functions also form a monoid with the normal functional compositon as an operation and the function which returns its input `(a) => a`
Functions also form a monoid with the normal functional composition as an operation and the function which returns its input `(a) => a`
--- ---
## Monad ## Monad
> A monad is an object with [`of`](#pointed-functor) and `chain` functions. `Chain` is like [map](#functor) except it unnests the resulting nested object. > A monad is an object with [`of`](#pointed-functor) and `chain` functions. `chain` is like [`map`](#functor) except it un-nests the resulting nested object.
```js ```js
['cat,dog', 'fish,bird'].chain(a => a.split(',')) // ['cat', 'dog', 'fish', 'bird'] ['cat,dog', 'fish,bird'].chain(a => a.split(',')) // ['cat', 'dog', 'fish', 'bird']
@ -358,7 +376,7 @@ Functions also form a monoid with the normal functional compositon as an operati
['cat,dog', 'fish,bird'].map(a => a.split(',')) // [['cat', 'dog'], ['fish', 'bird']] ['cat,dog', 'fish,bird'].map(a => a.split(',')) // [['cat', 'dog'], ['fish', 'bird']]
``` ```
You may also see `of` and `chain` referred to as `return` and `bind` (not be confused with the JS keyword/function...) in languages which provide Monad-like constructs as part of their standard library (e.g. Haskell, F#), on [Wikipedia](https://en.wikipedia.org/wiki/Monad_%28functional_programming%29) and in other literature. It's also important to note that `return` and `bind` are not part of the [Fantasy Land spec](https://github.com/fantasyland/fantasy-land) and are mentioned here only for the sake of people interested in learning more about Monads. You may also see `of` and `chain` referred to as `return` and `bind` (not to be confused with the JS keyword/function...) in languages which provide monad-like constructs as part of their standard library (e.g. Haskell, F#), on [Wikipedia](https://en.wikipedia.org/wiki/Monad_%28functional_programming%29) and in other literature. It's also important to note that `return` and `bind` are not part of the [Fantasy Land spec](https://github.com/fantasyland/fantasy-land) and are mentioned here only for the sake of people interested in learning more about monads.
--- ---
@ -375,19 +393,22 @@ let CoIdentity = v => ({
``` ```
Extract takes a value out of a functor. Extract takes a value out of a functor.
```js ```js
CoIdentity(1).extract() // 1 CoIdentity(1).extract() // 1
``` ```
Extend runs a function on the comonad. The function should return the same type as the Comonad. Extend runs a function on the comonad. The function should return the same type as the comonad.
```js ```js
CoIdentity(1).extend(co => co.extract() + 1) // CoIdentity(2) CoIdentity(1).extend(co => co.extract() + 1) // CoIdentity(2)
``` ```
--- ---
## Applicative Functor ## Applicative Functor
> An applicative functor is an object with an `ap` function. `Ap` applies a function in the object to a value in another object of the same type. > An applicative functor is an object with an `ap` function. `ap` applies a function in the object to a value in another object of the same type.
```js ```js
[(a) => a + 1].ap([1]) // [2] [(a) => a + 1].ap([1]) // [2]
@ -406,6 +427,7 @@ CoIdentity(1).extend(co => co.extract() + 1) // CoIdentity(2)
> A pair of transformations between 2 types of objects that is structural in nature and no data is lost. > A pair of transformations between 2 types of objects that is structural in nature and no data is lost.
For example, 2D coordinates could be stored as an array `[2,3]` or object `{x: 2, y: 3}`. For example, 2D coordinates could be stored as an array `[2,3]` or object `{x: 2, y: 3}`.
```js ```js
// Providing functions to convert in both directions makes them isomorphic. // Providing functions to convert in both directions makes them isomorphic.
const pairToCoords = (pair) => ({x: pair[0], y: pair[1]}) const pairToCoords = (pair) => ({x: pair[0], y: pair[1]})
@ -423,7 +445,8 @@ pairToCoords(coordsToPair({x: 1, y: 2})) // {x: 1, y: 2}
> An object that has an `equals` function which can be used to compare other objects of the same type. > An object that has an `equals` function which can be used to compare other objects of the same type.
Make array a setoid. Make array a setoid:
```js ```js
Array.prototype.equals = arr => { Array.prototype.equals = arr => {
var len = this.length var len = this.length
@ -446,7 +469,7 @@ Array.prototype.equals = arr => {
## Semigroup ## Semigroup
An object that has a `concat` function that combines it with another object of the same type. > An object that has a `concat` function that combines it with another object of the same type.
```js ```js
[1].concat([2]) // [1, 2] [1].concat([2]) // [1, 2]
@ -456,7 +479,7 @@ An object that has a `concat` function that combines it with another object of t
## Foldable ## Foldable
> An object that has a reduce function that can transform that object into some other type. > An object that has a `reduce` function that can transform that object into some other type.
```js ```js
let sum = list => list.reduce((acc, val) => acc + val, 0); let sum = list => list.reduce((acc, val) => acc + val, 0);
@ -468,11 +491,13 @@ sum([1, 2, 3]) // 6
## Traversable ## Traversable
--- ---
## Type Signatures ## Type Signatures
> Often functions will include comments that indicate the types of their arguments and return types. > Often functions will include comments that indicate the types of their arguments and return types.
There's quite a bit variance across the community but they often follow the following patterns: There's quite a bit of variance across the community but they often follow the following patterns:
```js ```js
// functionName :: firstArgType -> secondArgType -> returnType // functionName :: firstArgType -> secondArgType -> returnType
@ -489,7 +514,9 @@ If a function accepts another function as an argument it is wrapped in parenthes
// call :: (a -> b) -> a -> b // call :: (a -> b) -> a -> b
let call = f => x => f(x) let call = f => x => f(x)
``` ```
The letters `a`, `b`, `c`, `d` are used to signify that the argument can be of any type. For this map it takes a function that transforms a value of some type `a` into another type `b`, an array of values of type `a`, and returns an array of values of type `b`.
The letters `a`, `b`, `c`, `d` are used to signify that the argument can be of any type. For this `map` it takes a function that transforms a value of some type `a` into another type `b`, an array of values of type `a`, and returns an array of values of type `b`.
```js ```js
// map :: (a -> b) -> [a] -> [b] // map :: (a -> b) -> [a] -> [b]
let map = f => list => list.map(f) let map = f => list => list.map(f)