Haskell镜头获取器,比较两个镜头获取器的值

3

我尝试编写一个比较运算符,用于两个类型为lens getters的比较,并且它可以判断大于等于。

(.>=.) :: Ord a => Getting a s a -> Getting a s a -> Getting Bool s Bool

我有一个可行的解决方案,左侧是getter函数,右侧是数值(运算符.>=右侧没有.

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

1个回答

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),现在您需要将其转换为具有 toGetting

λ> 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

(当 (逆变 f,Profunctor p)=> Optic' p f s Bool 专门化为 Getting Bool s Bool 时,这就是你想要的。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接