Using the Haskell lens library for fmap lens

In the code below, my question is about the topmost function someFunc (all of the following is just to provide a complete example). I use get-syntax getter and fmap there. What is the lens way to implement someFunc ?

 import Control.Lens import Data.IntMap (IntMap) someFunc :: Farm -> IntMap Size someFunc farm = _barnSize <$> farm ^. farmBarns data Farm = Farm { _farmBarns :: IntMap Barn } farmBarns :: Lens' Farm (IntMap Barn) farmBarns = lens _farmBarns (\farm barns -> farm { _farmBarns = barns } ) type Size = (Int, Int) data Barn = Barn { _barnSize :: Size } barnSize :: Lens' Barn Size barnSize = lens _barnSize (\barn size -> barn { _barnSize = size } ) 
+5
source share
2 answers

Just replace _barnSize with (^. barnSize) or, equivalently, view barnSize :

 someFunc :: Farm -> IntMap Size someFunc farm = view barnSize <$> farm ^. farmBarns 

To solve the "100% lens" you can use the mapped setter. In this case, however, I do not think that there is a real advantage to this.

 someFunc :: Farm -> IntMap Size someFunc farm = (mapped %~ view barnSize) (farm ^. farmBarns) 

Another possible spelling involves using to to merge just one getter. This doesn’t buy you either, but it can be somewhat convenient if you want to continue working with the IntMap style in the lens by combining additional getters / bends, etc.

 someFunc :: Farm -> IntMap Size someFunc farm = farm ^. farmBarns . to (fmap (view barnSize)) 

There is a special purpose combinator that includes the combination to / (^.) . It is called views :

 someFunc :: Farm -> IntMap Size someFunc farm = views farmBarns (fmap (view barnSize)) farm 
+6
source

You can use mapped (or traversed ) to β€œmatch” the passing through with the lenses, in your case:

 someFunc :: Farm -> IntMap Size someFunc farm = farm ^. farmBarns & mapped %~ view barnSize 

This may be a little confusing, but here's what happens, I will add brackets to make it a little understandable

 someFunc :: Farm -> IntMap Size someFunc farm = (farm ^. farmBarns) & (mapped %~ (view barnSize)) 

We mainly use farm ^. farmBarns farm ^. farmBarns to get IntMap Barns from the farm, on the right side & we build the setter using %~ , which is the over infix, however the function which over passes its target, actually just focuses barnSize using the lens. view barnSize :: Barn -> Size .

Finally, we use & to tie it all together, which is equivalent to flip $ , and takes the setter from the right hand and uses it as a result of the left hand.

+2
source

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


All Articles