Skip to content

Commit 49a856f

Browse files
jethrolarsonhemanth
authored andcommitted
Moved Libraries to the bottom, added auto curry, endomorphism, some example implementations of .ap and .chain, and regenerated TOC (#102)
1 parent 946058d commit 49a856f

File tree

1 file changed

+71
-22
lines changed

1 file changed

+71
-22
lines changed

readme.md

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,17 @@ Examples are presented in JavaScript (ES2015). [Why JavaScript?](https://github.
88

99
Where applicable, this document uses terms defined in the [Fantasy Land spec](https://github.com/fantasyland/fantasy-land)
1010

11-
__Translations:__
11+
__Translations__
1212
* [Portuguese](https://github.com/alexmoreno/jargoes-programacao-funcional)
1313

14-
__Functional programming libraries and projects for JavaScript:__
15-
16-
* [ramda](https://github.com/ramda/ramda)
17-
* [lodash](https://github.com/lodash/lodash)
18-
* [underscore.js](https://github.com/jashkenas/underscore)
19-
* [lazy.js](https://github.com/dtao/lazy.js)
20-
* [maryamyriameliamurphies.js](https://github.com/sjsyrek/maryamyriameliamurphies.js)
21-
* [Haskell in ES6](https://github.com/casualjavascript/haskell-in-es6)
22-
23-
### Contents
24-
14+
__Table of Contents__
2515
<!-- RM(noparent,notop) -->
2616

27-
2817
* [Arity](#arity)
2918
* [Higher-Order Functions (HOF)](#higher-order-functions-hof)
3019
* [Partial Application](#partial-application)
3120
* [Currying](#currying)
21+
* [Auto Currying](#auto-currying)
3222
* [Function Composition](#function-composition)
3323
* [Purity](#purity)
3424
* [Side effects](#side-effects)
@@ -45,13 +35,16 @@ __Functional programming libraries and projects for JavaScript:__
4535
* [Lift](#lift)
4636
* [Referential Transparency](#referential-transparency)
4737
* [Equational Reasoning](#equational-reasoning)
38+
* [Lambda](#lambda)
39+
* [Lambda Calculus](#lambda-calculus)
4840
* [Lazy evaluation](#lazy-evaluation)
4941
* [Monoid](#monoid)
5042
* [Monad](#monad)
5143
* [Comonad](#comonad)
5244
* [Applicative Functor](#applicative-functor)
5345
* [Morphism](#morphism)
54-
* [Isomorphism](#isomorphism)
46+
* [Endomorphism](#endomorphism)
47+
* [Isomorphism](#isomorphism)
5548
* [Setoid](#setoid)
5649
* [Semigroup](#semigroup)
5750
* [Foldable](#foldable)
@@ -60,6 +53,7 @@ __Functional programming libraries and projects for JavaScript:__
6053
* [Union type](#union-type)
6154
* [Product type](#product-type)
6255
* [Option](#option)
56+
* [Functional Programming Libraries in JavaScript](#functional-programming-libraries-in-javascript)
6357

6458

6559
<!-- /RM -->
@@ -151,6 +145,24 @@ add2(10) // 12
151145

152146
```
153147

148+
## Auto Currying
149+
Transforming a function that takes multiple arguments into one that if given less than its correct number of arguments returns a function that takes the rest. When the function gets the correct number of arguments it is then evaluated.
150+
151+
Underscore, lodash, and ramda have a `curry` function that works this way.
152+
153+
```js
154+
const add = (x, y) => x + y;
155+
156+
const curriedAdd = _.curry(add);
157+
curreiedAdd(1, 2) // 3
158+
curreiedAdd(1) // (y) => 1 + y
159+
curreiedAdd(1)(2) // 3
160+
```
161+
162+
__Further reading__
163+
* [Favoring Curry](http://fr.umio.us/favoring-curry/)
164+
* [Hey Underscore, You're Doing It Wrong!](https://www.youtube.com/watch?v=m3svKOdZijA)
165+
154166
## Function Composition
155167

156168
The act of putting two functions together to form a third function where the output of one function is the input of the other.
@@ -335,12 +347,14 @@ Lifting is when you take a value and put it into an object like a [functor](#poi
335347
Some implementations have a function called `lift`, or `liftA2` to make it easier to run functions on functors.
336348

337349
```js
338-
const mult = (a, b) => a * b;
350+
const liftA2 = (f) => (a, b) => a.map(f).ap(b);
351+
352+
const mult = a => b => a * b;
339353

340-
const liftedMult = lift(mult); // this function now works on functors like array
354+
const liftedMult = liftA2(mult); // this function now works on functors like array
341355

342356
liftedMult([1, 2], [3]); // [3, 6]
343-
lift((a, b) => a + b)([1, 2], [3, 4]); // [4, 5, 5, 6]
357+
liftA2((a, b) => a + b)([1, 2], [3, 4]); // [4, 5, 5, 6]
344358
```
345359

346360
Lifting a one-argument function and applying it does the same thing as `map`.
@@ -464,9 +478,15 @@ compose(foo, identity) ≍ compose(identity, foo) ≍ foo
464478
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.
465479

466480
```js
481+
// Implementation
482+
Array.prototype.chain = function(f){
483+
return this.reduce((acc, it) => acc.concat(f(it)), []);
484+
};
485+
486+
// Usage
467487
['cat,dog', 'fish,bird'].chain((a) => a.split(',')) // ['cat', 'dog', 'fish', 'bird']
468488

469-
//Contrast to map
489+
// Contrast to map
470490
['cat,dog', 'fish,bird'].map((a) => a.split(',')) // [['cat', 'dog'], ['fish', 'bird']]
471491
```
472492

@@ -502,16 +522,23 @@ CoIdentity(1).extend((co) => co.extract() + 1) // CoIdentity(2)
502522
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.
503523

504524
```js
525+
// Implementation
526+
Array.prototype.ap = function(xs){
527+
return this.reduce((acc, f) => acc.concat(xs.map(f)), []);
528+
};
529+
530+
// Example usage
505531
[(a) => a + 1].ap([1]) // [2]
506532
```
507533

508-
This is useful if you have multiple applicative functors and you want to apply a function that takes multiple arguments to them.
534+
This is useful if you have two objects and you want to apply a binary function to their contents.
509535

510536
```js
537+
// Arrays that you want to combine
511538
const arg1 = [1, 2];
512539
const arg2 = [3, 4];
513540

514-
// function needs to be curried for this to work
541+
// combining function - must be curried for this to work
515542
const add = (x) => (y) => x + y;
516543

517544
const partiallyAppliedAdds = [add].ap(arg1); // [(y) => 1 + y, (y) => 2 + y]
@@ -527,7 +554,19 @@ partiallyAppliedAdds.ap(arg2); // [3, 4, 5, 6]
527554

528555
A transformation function.
529556

530-
## Isomorphism
557+
### Endomorphism
558+
559+
A function where the input type is the same as the output.
560+
561+
```js
562+
// uppercase :: String -> String
563+
const uppercase = (str) => str.toUpperCase();
564+
565+
// decrement :: Number -> Number
566+
const decrement = (x) => x - 1;
567+
```
568+
569+
### Isomorphism
531570

532571
A pair of transformations between 2 types of objects that is structural in nature and no data is lost.
533572

@@ -621,7 +660,7 @@ The letters `a`, `b`, `c`, `d` are used to signify that the argument can be of a
621660
const map = (f) => (list) => list.map(f)
622661
```
623662

624-
### Further reading
663+
__Further reading__
625664
* [Ramda's type signatures](https://github.com/ramda/ramda/wiki/Type-Signatures)
626665
* [Mostly Adaquate Guide](https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch7.html#whats-your-type)
627666
* [What is Hindley-Milner?](http://stackoverflow.com/a/399392/22425) on Stack Overflow
@@ -707,6 +746,16 @@ getNestedPrice({item: {price: 9.99}}); // Some(9.99)
707746

708747
`Option` is also known as `Maybe`. `Some` is sometimes called `Just`. `None` is sometimes called `Nothing`.
709748

749+
## Functional Programming Libraries in JavaScript
750+
751+
* [Ramda](https://github.com/ramda/ramda)
752+
* [Folktale](http://folktalejs.org)
753+
* [lodash](https://github.com/lodash/lodash)
754+
* [Underscore.js](https://github.com/jashkenas/underscore)
755+
* [Lazy.js](https://github.com/dtao/lazy.js)
756+
* [maryamyriameliamurphies.js](https://github.com/sjsyrek/maryamyriameliamurphies.js)
757+
* [Haskell in ES6](https://github.com/casualjavascript/haskell-in-es6)
758+
710759
---
711760

712761
__P.S:__ This repo is successful due to the wonderful [contributions](https://github.com/hemanth/functional-programming-jargon/graphs/contributors)!

0 commit comments

Comments
 (0)