一个棱镜是一种用于聚焦到乘积类型的光学器件,而仿射遍历是一种可以在1元素的0处进行聚焦的光学器件,即
这段话的意思是镜头可以放大产品类型,棱镜可以放大余产品类型,而仿射遍历可以放大代数数据类型(仍然是产品或余乘积)。是否与Cochoice或者Costrong有关(从Profunctor中删除一个乘积/余乘积而不是引入它)?但我无法从中恢复出天真的公式。{{因为需要上下文才能理解的术语没有翻译}}
AffineTraversal s t a b
与(s -> Maybe a, (s, b) -> t)
同构。据我所知,当适当编码棱镜时,将镜头与棱镜组合可以得到仿射遍历。
我有兴趣将那个(天真的)公式中的Maybe
移到setter侧,而不是getter侧,以便我可以拥有一种始终精确提取一个元素但可能无法放回的光学器件。
A
及其精化B
(B ⊆ A
)。那么就会有一个棱镜refined :: Prism' A B
:一个A
可能是有效的B
,也可能不是,但每个B
都可以被重新获取为A
。将Lens' C A
与refined
结合起来,我们就得到了一个仿射遍历。另一方面,可以想象一个比re refined
更聪明的光学工具unrefined
:如果A
是有效的B
,则它可以被转换为Just b
,否则为Nothing
。现在,如果我们将Lens' C B
与unrefined
结合起来,就得到了我们的对偶仿射遍历:它总是可以从C
获得A
,但将任何旧的A
放回可能会违反C
的不变量,并产生Nothing
而不是Just c
。可以通过类似的方式确保更复杂的不变量。
有趣的是,Scala的monocle库提供了用于细化类型的棱镜,但没有提供反向操作。
我很难为这些(s -> a, b -> Maybe t)
和(s -> a, (s, b) -> Maybe t)
小工具制定规则,想知道更抽象的光学公式是否有帮助。
我知道使用profunctor lens,我们可以
type Lens s t a b = forall p. Strong p => p a b -> p s t
type Prism s t a b = forall p. Choice p => p a b -> p s t
type AffineTraversal s t a b = forall p. (Strong p, Choice p) => p a b -> p s t
这段话的意思是镜头可以放大产品类型,棱镜可以放大余产品类型,而仿射遍历可以放大代数数据类型(仍然是产品或余乘积)。是否与Cochoice或者Costrong有关(从Profunctor中删除一个乘积/余乘积而不是引入它)?但我无法从中恢复出天真的公式。{{因为需要上下文才能理解的术语没有翻译}}
Strong
的对偶是Choice
,相应地,Lens
的对偶是Prism
。这使得AffineTraversal
的对偶是...AffineTraversal
。 - Benjamin HodgsonRe
来“翻转光学”,将Prisms a b s t
转换为(s -> a, b -> Maybe t)
的 profunctor 光学等效形式,详见这篇博客文章 http://oleg.fi/gists/posts/2017-04-18-glassery.html。 - Li-yao Xia