I've noticed I'm commonly building functions that get values using lenses, apply some function to the values and return the result. For example, to sum the elements of a pair
\pair -> (pair ^. _1) + (pair ^. _2)
I feel like there should be some combinator to combine getters first class and return another getter (maybe of type (b -> c -> d) -> Getter a b -> Getter a c -> Getter a d
). Any help?
You can always use the Applicative
instance for (->)
(+) <$> view _1 <*> view _2 :: Num a => (a,a) -> a
or, a little less generally, you might be aided by the Monoid
instance for Getter
s
>>> view (_1 <> _2) (Sum 1, Sum 2)
Sum {getSum = 3}
As is explained on the top of Control.Lens.Getter
, a Getter a b
is isomorphic to (a -> b)
. This means that they contains the same information and can be changed into each other at will. We can turn them into each other by using functions that the lens library provide:
fromGetter :: Getter a b -> (a -> b)
fromGetter g = view g
toGetter :: (a -> b) -> Getter a b
toGetter = to
With this knowledge you can use the Applicative
instance for (->)
, as J. Abrahamson has shown, to create the function you want:
myCombinator :: (b -> c -> d) -> Getter a b -> Getter a c -> Getter a d
myCombinator fn g1 g2 = toGetter (fn <$> fromGetter g1 <*> fromGetter g2)
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