我尝试为类型为
的两个lens getter编写一个大于等于的比较运算符(.>=.) :: Ord a => Getting a s a -> Getting a s a -> Getting Bool s Bool
我在左侧有一个吸气剂的工作解决方案,右侧有一个值(操作员.
右侧没有.>=
)
left .>= right = left . to (>= right)
我试过
left .>=. right = (>=) <$> use left <*> use right
但它有类型
(.>=.) :: (Ord a, MonadState s f) => Getting a s a -> Getting a s a -> f Bool
如何获得所需的返回类型Getting Bool s Bool
而不是f Bool
?
答案 0 :(得分:4)
你接近这个:
λ> 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
首先,使用view
代替use
; use
用于从州获取(因此MonadState
约束),这在这里似乎并不相关。
λ> 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
这为您提供了一项功能(MonadReader s f => f Bool
专门针对s -> Bool
),因此现在您需要将其转换为Getting
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
((Contravariant f, Profunctor p) => Optic' p f s Bool
专门针对Getting Bool s Bool
,所以这就是你想要的。)