I'm struggling with using the lens
library for a particular problem. I'm trying to pass
to another function, g
. I pass both the lens and the data structure because g
needs some shared information from the data structure as well as a piece of information. (If it helps, the data structure contains information on a joint probability distribution, but g
only works on either marginal and needs to know which marginal I'm looking at. The only difference between the two marginals is their mean with the rest of their definition being shared in the data structure).
My first attempt looked like this
f :: Functor f => Params -> ((Double -> f Double) -> Params -> f Params) -> a
f p l = g (l %~ upd $ p) l
where upd = ...
g p x = go p p^.x
but that fails during compilation because f
gets inferred as being Identity
for the update and Const Double
for the getter.
What's the best way to accomplish what I want to do? I can imagine being able to do one of the following:
Thanks for any help!
Daily disposable contacts are typically soft, flexible ones you should only wear once before tossing, the FDA explains. Depending on the brand, you can use extended wear contact lenses safely for up to 30 days.
Wearing daily contacts more often than recommended can greatly increase the risk for eye infection and other eye-related issues. It is important to follow your doctor's instructions when replacing and reusing contacts in order to maintain your eye health.
You can only wear daily disposable contacts for one day and you cannot use them more than once. Without exception, you should throw them out after removing them, whether it's at the end of the day or after only a few hours.
András Kovács answer shows how to achieve this with RankNTypes
. If you wish to avoid RankNTypes
, then you can use ALens
and cloneLens
:
f :: a -> ALens' a Int -> (Int, a)
f a l = (newvalue, a & cloneLens l .~ newvalue)
where oldvalue = a^.cloneLens l
newvalue = if oldvalue == 0 then 0 else oldvalue - 1
Control.Lens.Loupe provides operators and functions that work on ALens
instead of Lens
.
Note that in many cases, you should also be able to use <<%~
, which is like %~
but also returns the old value, or <%~
, which returns the new value:
f :: a -> LensLike' ((,) Int) a Int -> (Int, a)
f a l = a & l <%~ g
where g oldvalue = if oldvalue == 0 then 0 else oldvalue - 1
This has the advantage that it can also work with Isos
or sometimes also with Traversals
(when the target type is a Monoid
).
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