With the Haskell lens library, how do I treat getters as "first class"?

I noticed that I usually create functions that receive values ​​using lenses, apply some function to the values, and return a result. For example, to sum the elements of a pair \pair -> (pair ^. _1) + (pair ^. _2)

I feel that there must be some kind of combinator for combining the first class of getters and returning another recipient (perhaps like (b -> c -> d) -> Getter ab -> Getter ac -> Getter ad ). Any help?

+8
haskell lens
source share
2 answers

As explained at the top of Control.Lens.Getter , a Getter ab is isomorphic (a -> b) . This means that they contain the same information and can be changed as desired. We can turn them into each other using the functions provided by the lens library:

 fromGetter :: Getter ab -> (a -> b) fromGetter g = view g toGetter :: (a -> b) -> Getter ab toGetter = to 

With this knowledge, you can use the Applicative instance for (->) , as shown by J. Abrahamson, to create the desired function:

 myCombinator :: (b -> c -> d) -> Getter ab -> Getter ac -> Getter ad myCombinator fn g1 g2 = toGetter (fn <$> fromGetter g1 <*> fromGetter g2) 
+2
source share

You can always use Applicative instance for (->)

 (+) <$> view _1 <*> view _2 :: Num a => (a,a) -> a 

or, to a lesser extent, a Monoid instance for Getter s may help you

 >>> view (_1 <> _2) (Sum 1, Sum 2) Sum {getSum = 3} 
+3
source share

All Articles