首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定义profunctor透镜选择函数的问题

定义profunctor透镜选择函数的问题
EN

Stack Overflow用户
提问于 2018-10-23 16:08:20
回答 1查看 132关注 0票数 1

我正在摆弄profunctor光学器件,我遇到了一些我不太明白的事情。

Lens及其反转的profunctor编码如下:

代码语言:javascript
复制
type Optic p s t a b = p a b -> p s t

type Lens s t a b = forall p. Strong p => Optic p s t a b

type LensyReview t b = forall p. Costrong p => Optic p t t b b

您可以使用以下命令在它们之间来回自由转换

代码语言:javascript
复制
newtype Re p s t a b = Re { unRe :: p b a -> p t s }

instance Profunctor p => Profunctor (Re p s t) where
  dimap f g (Re p) = Re (p . dimap g f)

instance Strong p => Costrong (Re p s t) where
  unfirst  (Re p) = Re (p . first')
  unsecond (Re p) = Re (p . second')

instance Costrong p => Strong (Re p s t) where
  first'  (Re p) = Re (p . unfirst)
  second' (Re p) = Re (p . unsecond)

re :: Optic (Re p a b) s t a b -> Optic p b a t s
re optic = unRe (optic (Re id)))

现在,我尝试为profunctor透镜实现选择函数(https://hackage.haskell.org/package/lens-4.17/docs/Control-Lens-Lens.html#v:choosing)。

事实证明,这需要额外的类型类:

代码语言:javascript
复制
class Profunctor p => SumProfunctor p where
  (+++!) :: p a b -> p a' b' -> p (Either a a') (Either b b')

然后,如果我们在镜头中包含SumProfunctor,我们就可以写

代码语言:javascript
复制
choosing :: Lens s t a b -> Lens s' t' a b -> Lens (Either s s') (Either t t') a b
choosing optic optic' = \pab -> optic pab +++! optic' pab

但是,还需要有另一个“双”类型的类,它遵循Re的模式,

代码语言:javascript
复制
instance Unknown p => ProfunctorSum (Re p s t)
instance ProfunctorSum p => Unknown (Re p s t)

所以透镜是可逆的。

我得到的最接近的结果是:

代码语言:javascript
复制
class Profunctor p => Unknown p where
  unsum :: p (Either a a') (Either b b') -> (p a b -> r) -> (p a' b' -> r) -> r

因为有一个合理的实例用于标记它,然后您可以编写

代码语言:javascript
复制
instance Unknown p => SumProfunctor (Re p s t) where
  Re f +++! Re g = Re (\s -> unsum s f g)

但在另一个方向上定义它,即

代码语言:javascript
复制
instance SumProfunctor p => Unknown (Re p s t) where
  unsum = ???

看起来不太可能。

我在正确的轨道上,还是需要一些其他的方法?

EN

回答 1

Stack Overflow用户

发布于 2018-10-24 10:45:29

SumProfunctor等同于Choice,带有p +++ q = left p . right q

Cochoice是dual类:

代码语言:javascript
复制
instance Cochoice p => Choice (Re p s t) where
    left' (Re f) = Re (f . unleft)
    right' (Re f) = Re (f . unright)

instance Choice p => Cochoice (Re p s t) where
    unleft (Re f) = Re (f . left')
    unright (Re f) = Re (f . right')
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52944118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档