| Start | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
Lenses for records Simple recordLenses Managing records with repeating fields namesCreates a type class The Template Haskell extension is required for |
||||||||||
| Manipulating tuples with Lens Getting Setting Modifying
|
||||||||||
| Lens and Prism A To be more clear, we have With this intuition, some standard combinators can be interpreted parallel to one another
Another way to think about it is that a value of type |
||||||||||
| Stateful Lenses Lens operators have useful variants that operate in stateful contexts. They are obtained by replacing Note: The stateful variants aren't expected to change the type, so they have the Getting rid of |
||||||||||
| Lenses compose If you have a
More than just composing |
||||||||||
| Writing a lens without Template Haskell To demystify Template Haskell, suppose you have then produces (more or less) There's nothing particularly magical going on, though. You can write these yourself: Essentially, you want to "visit" your lens' "focus" with the |
||||||||||
| Traversals A Any type We can use a A |
||||||||||
| Classy Lenses In addition to the standard will create |
||||||||||
| Fields with makeFields (This example copied from this StackOverflow answer (opens new window)) Let's say you have a number of different data types that all ought to have a lens with the same name, in this case Then in ghci: So what it's actually done is declared a class In case it helps, using ghci -ddump-splices Foo.hs: So the first splice made the class This also works if you import the RemarksWhat is a Lens?Lenses (and other optics) allow us to separate describing how we want to access some data from what we want to do with it. It is important to distinguish between the abstract notion of a lens and the concrete implementation. Understanding abstractly makes programming with FocusingAn important concept in understanding abstractly is the notion of focusing. Important optics focus on a specific part of a larger data structure without forgetting about the larger context. For example, the lens Once we have focus, we can then talk about which operations we are allowed to perform with a lens. Given a
These correspond to the well-known Other OpticsWe can talk about other optics in a similar fashion.
Each optic focuses in a different way, as such, depending on which type of optic we have we can perform different operations. CompositionWhat's more, we can compose any of the two optics we have so-far discussed in order to specify complex data accesses. The four types of optics we have discussed form a lattice, the result of composing two optics together is their upper bound. For example, if we compose together a lens and a prism, we get a traversal. The reason for this is that by their (vertical) composition, we first focus on one part of a product and then on one part of a sum. The result being an optic which focuses on precisely zero or one parts of our data which is a special case of a traversal. (This is also sometimes called an affine traversal). In HaskellThe reason for the popularity in Haskell is that there is a very succinct representation of optics. All optics are just functions of a certain form which can be composed together using function composition. This leads to a very light-weight embedding which makes it easy to integrate optics into your programs. Further to this, due to the particulars of the encoding, function composition also automatically computes the upper bound of two optics we compose. This means that we can reuse the same combinators for different optics without explicit casting. |
Read Article
https://develop.horje.com/learn/1434/reference