我目前正在学习 Haskell lens 包的教程,因此我可以更好地理解底层的数学基础。我正在经历
Prism
s。
type Prism s t a b = forall p f. (Applicative f, Choice p) => p a (f b) -> p s (f t)
我们发现棱镜实际上是
b -> t
和 s -> Either t a
。我们可以直接展示这种同构。
-- Note: Stripping out the APrism / AReview type synonyms used
-- in Control.Lens for simplicity.
prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b
prism bt seta = dimap seta (either pure (fmap bt)) . right'
matching :: Prism s t a b -> s -> Either t a
matching aprism s = let Market _ f = aprism (Market Identity Right) in
left runIdentity $ f s
review :: Prism s t a b -> b -> t
review areview = runIdentity . unTagged . areview . Tagged . Identity
Tagged
和Market
的来源)
Choice
有点只是Strong
,但在Either
而不是(,)
”。所以我想知道如果用 Choice
替换 Strong
会得到什么样的棱镜状的东西。我期待写
type ProductPrism s t a b = forall p f. (Applicative f, Strong p) => p a (f b) -> p s (f t)
并发现
ProductPrism s t a b
与(b -> t, s -> (t, a))
同构。但当我去写这些同构时,我发现了两件事:
b -> t
部分实际上与这里无关(构建ProductPrism
不需要它)pure
,所以我们可以用Apply
。所以我就这样结束了。
type ProductPrism s t a b = forall p f. (Apply f, Strong p) => p a (f b) -> p s (f t)
-- Construct ProductPrism from (s -> (t, a))
productPrism :: (s -> (t, a)) -> ProductPrism s t a b
productPrism sta = dimap sta (\(t, fb) -> t <$ fb) . second'
-- Consume ProductPrism into (s -> (t, a))
split :: ProductPrism (Semi.First a) s t a -> s -> (t, a)
split pprism s = go $ pprism (\a -> (Semi.First a, a)) s
where go (Semi.First a, t) = (t, a)
其中
Semi.First
是半群First
(不是幺半群版本)。
所以
ProductPrism s t a b
,正如我所定义的,只是 s -> (t, a)
和一个滑稽地未使用的 b
参数。
我的问题是:这种类型有用吗?此函数参考是否有一个众所周知的名称,例如
Lens
或 Prism
或 Traversal
?它是否像许多其他光学器件一样为我们提供了任何有用的抽象?
我认为您在
c
中选择了错误的Strong
参数。不应该是c ~ t
;应该是c ~ s
。所以,我读到您正在寻找以下内容:
type PPrism s t a b = forall p f. (Functor f, Strong p) => p a (f b) -> p s (f t)
pprism :: (s -> a) -> (b -> s -> t) -> PPrism s t a b
pprism sa bst = dimap (\s -> (s, sa s)) (\(s, fb) -> flip bst s <$> fb) . second'
unprism :: PPrism s t a b -> ((s -> a), (b -> s -> t))
unprism pp = (sa, bst)
where sa = getConst . pp (Const . id)
bst b = runIdentity . pp (const (Identity b))
简而言之,这实际上只是一个镜头。 (或者,如果您选择
Applicative f
,则进行遍历。)
这有道理,对吧? A
Prism
是基于具有 Choice
的函子的和类型的光学推广。 Lens
是基于带有 Strong
的函子的产品类型的光学概括,尽管我们通常只是用 p ~ (->)
来定义它。