我喜欢镜头包里的mapped。
mapped :: Prelude.Functor f => Setter (f a) (f b) a b 然而,我最近开始使用category包中的Functor (从这里开始,我将category的Functor称为Functor,否则使用Prelude.Functor ),因此我的mapped不再工作。
所以我想做一个可以和Functor一起工作的mapped版本。对于所有需要它的人来说,Functor的友好签名如下所示:
class (Category s, Category t) => Functor (s :: α -> α -> *) (t :: β -> β -> *) (f :: α -> β) where
map :: s a b -> t (f a) (f b)这采用了普通fmap中的两个(->),并将它们替换为满足Category的s和t。
因此,如果我们想要替换mapped,我们需要用满足泛型Category的类型替换适当的(->)。所以我们取消了Setter的别名
mapped ::
Prelude.Functor f =>
( forall g. Settable g =>
(a -> g b) -> (f a) -> g (f b)
)为了前进,我们将看看over,因为我们希望它是这样的:
over mapped = map现在我们来看一下over (解包ASetter)的实现:
over :: ((a -> Identity b) -> s -> Identity t) -> (a -> b) -> s -> t
over l f = runIdentity #. l (Identity #. f)我们可以从中得到一点信息。我们知道runIdentity、(#.)的类型和目标。如果我们倒着工作
(#.) runIdentity (mapped (Identity #. f)) ::
Category t => t (f a) (f b)
mapped (Identity #. f) ::
( Category t
, Profunctor t
, Coercible (f b) z
)
=> t (f a) z这是一个很好的证据,证明第三个(->)应该被一个通用类别取代,也是第二个不应该被替换的好证据。
mapped ::
( Functor s t f
, Category s
, Category t
) =>
( forall g. Settable g =>
(s a (g b)) -> t (f a) (g (f b))
)现在我被卡住了。在这里,我觉得我好像在紧贴我的概念支持。我不知道这个类型是否正确,或者我是否遗漏了什么。即使我知道这种类型,我也不确定我将如何实现mapped或over。我习惯于使用镜头包外的预先构建的组合体来构建我的镜头,我认为一旦我不再使用Setter,这些组合体就不会对我有帮助。
如何才能从我所处的位置到达Functor的有效mapped实现?
发布于 2020-02-24 19:47:25
我相信这个类型是绝对正确的。仔细查看代码,mapped被定义为
mapped = taintedDot . fmap . untaintedDot其中taintedDot、untaintedDot是Settable的方法。正如@leftaroundabout的评论指出的那样,这可能是翻译的难点-你需要一个等价的类别类,尽管它的确切含义超出了我的能力范围。
天真的猜测是
class Settable f where
untainted :: Category c => c (f a) a
tainted :: Category c => c a (f a)它们看起来很像Monad和Comonad操作,所以可能
class (forall c. Monad c f, forall c. Comonad c f) => Settable f where
untainted :: Category c => c (f a) a
untainted = counit
tainted :: Category c => c a (f a)
tainted = unit其他选择..。
也就是说,你可以欺骗- Category中的Profunctor等价物只是一个Arrow,因为你可以将Hask箭头提升到分类箭头。如果您的Categorys也是Arrows,那么您可以这样做
data Cheat c a b = Cheat { unCheat :: c a b }
instance (Arrow c) => Profunctor (Cheat c) where
lmap f = (arr f >>>)
rmap f = (>>> arr f)然后偷偷进入Cheat
mapped' ::
( Functor s t f
, Arrow s
, Arrow t
) =>
( forall g. Settable g =>
(s a (g b)) -> t (f a) (g (f b))
)
mapped' = unCheat . taintedDot . Cheat . map . unCheat . untaintedDot . Cheathttps://stackoverflow.com/questions/60369118
复制相似问题