“凋零”的 Profunctor 表示是啥?
Posted
技术标签:
【中文标题】“凋零”的 Profunctor 表示是啥?【英文标题】:What's the Profunctor Representation of "Wither"?“凋零”的 Profunctor 表示是什么? 【发布时间】:2021-02-14 10:17:13 【问题描述】:This article by Chris Penner谈“枯萎光学”;可用于从结构中过滤项目的光学元件。
本文对这些光学元件使用以下“Van Laarhoven”表示:
type Wither s t a b = forall f. Alternative f => (a -> f b) -> s -> f t
大多数(如果不是全部)Van Laarhoven 光学具有等效的 profunctor 表示。例如镜头:
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
相当于:
type Lens s t a b = forall p. Strong p => p a b -> p s t
Wither
也有 Profactor 代表吗?如果是这样,它是什么?
【问题讨论】:
有趣的问题!我的第一个想法是它只是Choice
加上其他东西,也就是说,我认为你想用 Prism
过滤,但有一些额外的限制。例如,我认为您不能返回任何未通过您过滤的谓词的元素,否则它不是有效的Traversal
。也可能与 At
之类的索引光学器件有某种关系——我可以将过滤器视为将结构“划分”为两半,即通过谓词的部分和不通过谓词的部分。
也许Conjoined
和indices
相关?
【参考方案1】:
克里斯在这里;这是我对 Profunctor 光学表示的看法:
Here's the profunctor class:
import Data.Profunctor
import Data.Profunctor.Traversing
import Control.Applicative
class (Traversing p) => Withering p where
cull :: (forall f. Alternative f => (a -> f b) -> (s -> f t)) -> p a b -> p s t
instance Alternative f => Withering (Star f) where
cull f (Star amb) = Star (f amb)
instance Monoid m => Withering (Forget m) where
cull f (Forget h) = Forget (getAnnihilation . f (AltConst . Just . h))
where
getAnnihilation (AltConst Nothing) = mempty
getAnnihilation (AltConst (Just m)) = m
newtype AltConst a b = AltConst (Maybe a)
deriving stock (Eq, Ord, Show, Functor)
instance Monoid a => Applicative (AltConst a) where
pure _ = (AltConst (Just mempty))
(AltConst Nothing) <*> _ = (AltConst Nothing)
_ <*> (AltConst Nothing) = (AltConst Nothing)
(AltConst (Just a)) <*> (AltConst (Just b)) = AltConst (Just (a <> b))
instance (Semigroup a) => Semigroup (AltConst a x) where
(AltConst Nothing) <> _ = (AltConst Nothing)
_ <> (AltConst Nothing) = (AltConst Nothing)
(AltConst (Just a)) <> (AltConst (Just b)) = AltConst (Just (a <> b))
instance (Monoid a) => Monoid (AltConst a x) where
mempty = (AltConst (Just mempty))
instance Monoid m => Alternative (AltConst m) where
empty = (AltConst Nothing)
(AltConst Nothing) <|> a = a
a <|> (AltConst Nothing) = a
(AltConst (Just a)) <|> (AltConst (Just b)) = (AltConst (Just (a <> b)))
如果您对出现的一些光学器件感兴趣,我已经实现了其中的一些 here:
绝对有可能有其他解释或一些更简单的表示,但目前这似乎可以解决问题。如果其他人有其他想法,我很乐意看到他们!
如果您有任何其他问题,很乐意多聊!
【讨论】:
拥有一个类型类方法将 Van Laarhoven 表示“提升”到 profunctor 表示上是一个非常漂亮的技巧! 确实!它使比较变得非常容易,看看来自 Traversing 的wander;请注意,它们在traverse'
方面具有“等效”实现。我们可以对 wither'
做同样的事情,如果我们想采用 Witherable 或 Compactable 依赖项,但 cull
本身可以正常工作,您始终可以稍后使用 cull
实现 wither'
。以上是关于“凋零”的 Profunctor 表示是啥?的主要内容,如果未能解决你的问题,请参考以下文章