@@ -52,6 +52,7 @@ __Table of Contents__
|
52 | 52 | * [Setoid](#setoid)
|
53 | 53 | * [Semigroup](#semigroup)
|
54 | 54 | * [Foldable](#foldable)
|
| 55 | +* [Lens](#lens) |
55 | 56 | * [Type Signatures](#type-signatures)
|
56 | 57 | * [Algebraic data type](#algebraic-data-type)
|
57 | 58 | * [Sum type](#sum-type)
|
@@ -729,6 +730,56 @@ const sum = (list) => list.reduce((acc, val) => acc + val, 0)
|
729 | 730 | sum([1, 2, 3]) // 6
|
730 | 731 | ```
|
731 | 732 |
|
| 733 | +## Lens ## |
| 734 | +A lens is a structure (often an object or function) that pairs a getter and a non-mutating setter for some other data |
| 735 | +structure. |
| 736 | + |
| 737 | +```js |
| 738 | +// Using [Ramda's lens](http://ramdajs.com/docs/#lens) |
| 739 | +const nameLens = R.lens( |
| 740 | +// getter for name property on an object |
| 741 | +(obj) => obj.name, |
| 742 | +// setter for name property |
| 743 | +(val, obj) => Object.assign({}, obj, {name: val}) |
| 744 | +) |
| 745 | +``` |
| 746 | + |
| 747 | +Having the pair of get and set for a given data structure enables a few key features. |
| 748 | + |
| 749 | +```js |
| 750 | +const person = {name: 'Gertrude Blanch'} |
| 751 | + |
| 752 | +// invoke the getter |
| 753 | +R.view(nameLens, person) // 'Gertrude Blanch' |
| 754 | + |
| 755 | +// invoke the setter |
| 756 | +R.set(nameLens, 'Shafi Goldwasser', person) // {name: 'Shafi Goldwasser'} |
| 757 | + |
| 758 | +// run a function on the value in the structure |
| 759 | +R.over(nameLens, uppercase, person) // {name: 'GERTRUDE BLANCH'} |
| 760 | +``` |
| 761 | + |
| 762 | +Lenses are also composable. This allows easy immutable updates to deeply nested data. |
| 763 | + |
| 764 | +```js |
| 765 | +// This lens focuses on the first item in a non-empty array |
| 766 | +const firstLens = R.lens( |
| 767 | +// get first item in array |
| 768 | +xs => xs[0], |
| 769 | +// non-mutating setter for first item in array |
| 770 | +(val, [__, ...xs]) => [val, ...xs] |
| 771 | +) |
| 772 | + |
| 773 | +const people = [{name: 'Gertrude Blanch'}, {name: 'Shafi Goldwasser'}] |
| 774 | + |
| 775 | +// Despite what you may assume, lenses compose left-to-right. |
| 776 | +R.over(compose(firstLens, nameLens), uppercase, people) // [{'name': 'GERTRUDE BLANCH'}, {'name': 'Shafi Goldwasser'}] |
| 777 | +``` |
| 778 | + |
| 779 | +Other implementations: |
| 780 | +* [partial.lenses](https://.com/calmm-js/partial.lenses) - Tasty syntax sugar and a lot of powerful features |
| 781 | +* [nanoscope](http://www.kovach.me/nanoscope/) - Fluent-interface |
| 782 | + |
732 | 783 | ## Type Signatures
|
733 | 784 |
|
734 | 785 | Often functions in JavaScript will include comments that indicate the types of their arguments and return values.
|
|
0 commit comments