首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用类别的Functor进行映射

使用类别的Functor进行映射
EN

Stack Overflow用户
提问于 2020-02-24 11:19:33
回答 1查看 112关注 0票数 3

我喜欢镜头包里的mapped

代码语言:javascript
复制
mapped :: Prelude.Functor f => Setter (f a) (f b) a b 

然而,我最近开始使用category包中的Functor (从这里开始,我将category的Functor称为Functor,否则使用Prelude.Functor ),因此我的mapped不再工作。

所以我想做一个可以和Functor一起工作的mapped版本。对于所有需要它的人来说,Functor的友好签名如下所示:

代码语言:javascript
复制
class (Category s, Category t) => Functor (s :: α -> α -> *) (t :: β -> β -> *) (f :: α -> β) where
  map :: s a b -> t (f a) (f b)

这采用了普通fmap中的两个(->),并将它们替换为满足Categoryst

因此,如果我们想要替换mapped,我们需要用满足泛型Category的类型替换适当的(->)。所以我们取消了Setter的别名

代码语言:javascript
复制
mapped ::
  Prelude.Functor f =>
    ( forall g. Settable g =>
      (a -> g b) -> (f a) -> g (f b)
    )

为了前进,我们将看看over,因为我们希望它是这样的:

代码语言:javascript
复制
over mapped = map

现在我们来看一下over (解包ASetter)的实现:

代码语言:javascript
复制
over :: ((a -> Identity b) -> s -> Identity t) -> (a -> b) -> s -> t
over l f = runIdentity #. l (Identity #. f)

我们可以从中得到一点信息。我们知道runIdentity(#.)的类型和目标。如果我们倒着工作

代码语言:javascript
复制
(#.) 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

这是一个很好的证据,证明第三个(->)应该被一个通用类别取代,也是第二个不应该被替换的好证据。

代码语言:javascript
复制
mapped ::
  ( Functor s t f
  , Category s
  , Category t
  ) =>
    ( forall g. Settable g =>
      (s a (g b)) -> t (f a) (g (f b))
    )

现在我被卡住了。在这里,我觉得我好像在紧贴我的概念支持。我不知道这个类型是否正确,或者我是否遗漏了什么。即使我知道这种类型,我也不确定我将如何实现mappedover。我习惯于使用镜头包外的预先构建的组合体来构建我的镜头,我认为一旦我不再使用Setter,这些组合体就不会对我有帮助。

如何才能从我所处的位置到达Functor的有效mapped实现?

EN

回答 1

Stack Overflow用户

发布于 2020-02-24 19:47:25

我相信这个类型是绝对正确的。仔细查看代码,mapped被定义为

代码语言:javascript
复制
mapped = taintedDot . fmap . untaintedDot

其中taintedDotuntaintedDotSettable的方法。正如@leftaroundabout的评论指出的那样,这可能是翻译的难点-你需要一个等价的类别类,尽管它的确切含义超出了我的能力范围。

天真的猜测是

代码语言:javascript
复制
class Settable f where
  untainted :: Category c => c (f a) a
  tainted   :: Category c => c a (f a)

它们看起来很像MonadComonad操作,所以可能

代码语言:javascript
复制
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,那么您可以这样做

代码语言:javascript
复制
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

代码语言:javascript
复制
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 . Cheat
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60369118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档