A Setter is an optic that can see into a structure and set or modify its focus.
It is a generalization of map.
A structure S that has a focus A to which we can apply a function (A) -> B to S and get T.
For example, S == List<Int> to which we apply (Int) -> String and we get T == List<String>.
List<Int>.map(f: (Int) -> String): List<String>PSetter#modify(s: List<Int>, f: (Int) -> String): List<String>You can get a Setter for any existing map.
To create your own Setter, you need to define how to apply (A) -> B to S.
A Setter<Player, Int> can set and modify the value of Player. So we need to define how to apply a function (Int) -> Int to Player.
Unlike a regular set function, a Setter composes. Similar to a Lens, we can compose Setters to focus into nested structures and set or modify a value.
Setter can be composed with all optics but Getter and Fold. It results in the following optics:
| Iso | Lens | Prism | Optional | Getter | Setter | Fold | Traversal | |
|---|---|---|---|---|---|---|---|---|
| Setter | Setter | Setter | Setter | Setter | X | Setter | X | Setter |
When dealing with polymorphic types, we can also have polymorphic setters that allow us to morph the type of the focus.
Previously, when we used a Setter<List<Int>, Int>, it was able to morph the Int values in the constructed type List<Int>.
With a PSetter<List<Int>, List<String>, Int, String>, we can morph an Int value to a String value and thus also morph the type from List<Int> to List<String>.
Arrow provides SetterLaws in the form of test cases for internal verification of lawful instances and third party apps creating their own setters.
Do you like Arrow?
✖