Suppose I have a function which extracts some inner value using other inner value from an outer value
func :: outer -> inner1 -> inner2
Then I have a function which cretes a lens between outer value and some other value using this inner2 value
existingLensFunc :: inner2 -> Lens' outer result
Is there a way to create another function which creates a lens betwee outer value and result value using inner1 value?
finalLens :: inner1 -> Lens' outer result
In other words, is there a better way to write this?
finalLens inner1 = lens getter setter
where setter outer result = let inner2 = func outer inner1 in set (existingLens inner2) result outer
getter outer = let inner2 = func outer inner1 in view (existingLens inner2) outer
Let's unshorten the types...
existingLensFunc
:: Inner2 -> (∀ f . Functor f => (Result -> f Result) -> Outer -> f Outer)
≡ ∀ f . Functor f => Inner2 -> (Result -> f Result) -> Outer -> f Outer
finalLens
:: ∀ f . Functor f => Inner1 -> (Result -> f Result) -> Outer -> f Outer
There's an evident place to “grab off” an Outer
here: from the last argument.
finalLens inner1 fres outer = existingLensFunc (func outer inner1) fres outer