What is a clean way to call a function using multiple Getters from Control.Lens.

Given some data structure with specific lenses, for example:

import Control.Lens data Thing = Thing { _a :: String , _b :: String , _c :: Int , _d :: Int } makeLenses ''Thing 

And given some function that I want to call using several getters, for example:

 fun :: Int -> String -> Int -> String -> Bool fun = undefined 

I am currently getting a lot of ugliness with parens to access each field, for example:

 thing = Thing "hello" "there" 5 1 answer = fun (thing^.c) (thing^.a) (thing^.d) (thing^.b) 

Given the brevity of the lens library in most other situations, I was hoping for something more elegant, but I cannot find combinators to help in this particular case.

+4
source share
1 answer

Since any lens can be used both in viewing mode and in setting mode, we need to at least specify view X for each lens X. But for any lens l :: Lens' ab , view l has a type, for example, a -> b , if you translate some noise MonadReader .

Thus, we can get rid of some repetition by using the Applicative instance for ((->) a) .

 thing & fun <$> view c <*> view a <*> view d <*> view b 
+4
source

Source: https://habr.com/ru/post/1492561/


All Articles