这个类似棱镜的光学器件叫什么名字,它有什么用处吗?

问题描述 投票:0回答:1

我目前正在学习 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))
同构。但当我去写这些同构时,我发现了两件事:

  1. b -> t
    部分实际上与这里无关(构建
    ProductPrism
    不需要它)
  2. 我们不需要
    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
?它是否像许多其他光学器件一样为我们提供了任何有用的抽象?

haskell haskell-lens lenses
1个回答
1
投票

我认为您在

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 ~ (->)
来定义它。

© www.soinside.com 2019 - 2024. All rights reserved.