Composition
All optics compose with compose(outer, inner).
import { Lens, compose } from '@fuiste/optics'
const address = Lens<Person>().prop('address')
const city = Lens<Address>().prop('city')
const personCity = compose(address, city)
// Lens<Person, string>
Result Matrix
| outer / inner | Lens | Prism | Iso | Traversal | Getter | Fold |
|---|---|---|---|---|---|---|
| Lens | Lens | Prism | Lens | Traversal | Getter | Fold |
| Prism | Prism | Prism | Prism | Traversal | Fold | Fold |
| Iso | Lens | Prism | Iso | Traversal | Getter | Fold |
| Traversal | Traversal | Traversal | Traversal | Traversal | Fold | Fold |
| Getter | Getter | Fold | Getter | Fold | Getter | Fold |
| Fold | Fold | Fold | Fold | Fold | Fold | Fold |
Rules Of Thumb
Foldis contagious.Getterplus partial or multiple focus becomesFold.Traversalabsorbs writable optics into anotherTraversal.Isois transparent unless both sides areIso.LensplusLensis stillLens.- Anything involving a partial writable path tends toward
Prism.
Nested Composition
Composition is binary, so compose longer paths by nesting.
const allEmployeeNames = compose(compose(employees, eachEmployee), name)
Yes, a variadic compose would be cute. No, the type inference gods do not grant wishes for free.