首页 > 解决方案 > 两侧部分转换的光学元件

问题描述

Prism就像Iso除了两个转换之一是部分的。是否有两种转换都是部分的光学器件?

当然可以创建一个类型(s -> Maybe a, b -> Maybe t),但我想知道这样的事情是否可以表示为Optic _ _

标签: haskellhaskell-lenslenses

解决方案


您可以通过用Kleisli 类别上的 profunctors(这里是monad)替换 Hask 上的 profunctors(即,这是as an定义中的约束)来将Isos(即(s -> a, b -> t))概括为。(s -> m a, b -> m t)ProfunctorIsoOpticMaybe

class Monad m => KProfunctor m p where
  dimapM :: (s -> m a) -> (b -> m t) -> p a b -> p s t

-- dimapM pure pure = id
-- dimapM f g . dimapM h i = dimapM (h >=> f) (g >=> i)

type Optic p s t a b = p a b -> p s t
type KIso m s t a b = forall p. KProfunctor m p => Optic p s t a b

要构造这样的 profunctor 的一个示例,请首先使用(s -> m a, b -> m t)我们尝试使用的伪 iso 类型,并将sandt作为主要索引:

data PseudoIso m a b s t = MkPseudoIso
  { toM :: s -> m a
  , fromM :: b -> m t
  }

instance Monad m => KProfunctor m (PseudoIso m) where
  -- exercise for the reader
  • 要从PseudoIsoKIso,请使用dimapM( 的字段PseudoIso正是 的 参数的正确类型dimapM
  • to go from KIsotoPseudoIso部分应用于身份PseudoIso a b a b

实际上,它不一定是 Kleisli 类别。任何类别的 profunctor(:->) :: k -> k -> Type都会为您提供以下形式的光学类(s :-> a, b :-> t)

Choice注意:你可以定义一个with的实例KProfunctor Maybe,所以也许一切都应该被专门化,Maybe所以Choice可以合理地添加为 的超类KProfunctor,然后KIso是 的子类型Prism


推荐阅读