Could someone explain functional lenses to me? It's a surprisingly difficult subject to google for and I haven't made any progress. All I know is that they provide similar get/set functionality than in OO.
Composable Getters and Setters for Functional Programming A lens is a composable pair of pure getter and setter functions which focus on a particular field inside an object, and obey a set of axioms known as the lens laws. Think of the object as the whole and the field as the part.
Lenses provide a means to decouple an object's shape from the logic operating on that object. It accomplishes this using the getter/setter pattern to 'focus in' on a sub-part of the object, which then isolates that sub-part for reads and writes without mutating the object.
A lens is a first-class reference to a subpart of some data type. For instance, we have _1 which is the lens that "focuses on" the first element of a pair. Given a lens there are essentially three things you might want to do. View the subpart. Modify the whole by changing the subpart.
A lens consists of two functions, a getter and a setter:
data Lens a b = Lens { getter :: a -> b, setter :: b -> a -> a }
For example, we might have lenses for the first and second parts of a pair:
fstLens :: Lens (a, b) a fstLens = Lens fst $ \x (a, b) -> (x, b) sndLens :: Lens (a, b) b sndLens = Lens snd $ \x (a, b) -> (a, x)
The real convenience of lenses is that they compose:
compose :: Lens b c -> Lens a b -> Lens a c compose f g = Lens (getter f . getter g) $ \c a -> setter g (setter f c (getter g a)) a
And they mechanically convert to State
transitions:
lensGet :: MonadState s m => Lens s a -> m a lensGet = gets . getter lensSet :: MonadState s m => Lens s b -> b -> m () lensSet f = modify . setter f lensMod :: MonadState s m => Lens s b -> (b -> b) -> m () lensMod f g = modify $ setter f =<< g . getter f (+=) :: (MonadState s m, Num b) => Lens s b -> b -> m () f += x = lensMod f (+ x)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With