I try to write a comparison operator greater-than-equals for two lens getters with type
(.>=.) :: Ord a => Getting a s a -> Getting a s a -> Getting Bool s Bool
I have a working solution for a getter on the left side and a value on the right side (no .
on the right side of the operator .>=
)
left .>= right = left . to (>= right)
I tried
left .>=. right = (>=) <$> use left <*> use right
but it has type
(.>=.) :: (Ord a, MonadState s f) => Getting a s a -> Getting a s a -> f Bool
How can I get the desired return type Getting Bool s Bool
instead of f Bool
?
You're close with this:
λ> left .>=. right = (>=) <$> use left <*> use right
(.>=.) ::
(Ord a, Control.Monad.State.Class.MonadState s f) =>
Getting a s a -> Getting a s a -> f Bool
First, use view
in instead of use
; use
is for getting from state (hence the MonadState
constraint), which doesn't seem relevant here.
λ> left .>=. right = (>=) <$> view left <*> view right
(.>=.) ::
(Ord a, Control.Monad.Reader.Class.MonadReader s f) =>
Getting a s a -> Getting a s a -> f Bool
That gives you a function (MonadReader s f => f Bool
specializes to s -> Bool
), so now you need to turn this into a Getting
with to
.
λ> left .>=. right = to $ (>=) <$> view left <*> view right
(.>=.) ::
(Ord a, Contravariant f, Profunctor p) =>
Getting a s a -> Getting a s a -> Optic' p f s Bool
(And (Contravariant f, Profunctor p) => Optic' p f s Bool
specializes to Getting Bool s Bool
, so this is what you want.)