当前位置: 首页 > 知识库问答 >
问题:

两个函子的合成是一个函子

孔鹤龄
2023-03-14

在前面的回答中,Petr Pudlak定义了cfunctor类,用于不同于从Hask到Hask的函数。使用类型族重写它,它看起来像

class CFunctor f where
  type Dom f :: * -> * -> *               -- domain category
  type Cod f :: * -> * -> *               -- codomain category
  cmap :: Dom f a b -> Cod f (f a) (f b)  -- map morphisms across categories
instance CFunctor Maybe where
  type Dom Maybe = (->)                   -- domain is Hask
  type Cod Maybe = (->)                   -- codomain is also Hask 
  cmap f = \m -> case m of
                   Nothing -> Nothing
                   Just x  -> Just (f x)

在范畴理论中,每当F:c-->D是函子,而G:d-->E是函子时,那么组成GF:c-->E也是函子。

我想用哈斯克尔来表达这一点。由于我不能编写实例CFunctor(f.g),我引入了一个包装类:

newtype Wrap g f a = Wrap { unWrap :: g (f a) }

在编写cfunctor实例时,我得到了以下内容

instance (CFunctor f, CFunctor g, Cod f ~ Dom g) => CFunctor (Wrap g f) where
  type Dom (Wrap g f) = Dom f
  type Cod (Wrap g f) = Cod g
  cmap = undefined

共有1个答案

双恩
2023-03-14

给定函子F:C→DG:D→E,函子组合G12月F:C→E是类别CE之间对象的映射,例如(G_p_f)(X)=G(F(X))和态性之间的映射,例如(G_p_f)(F)=G(F(F))

这表明您的cfunctor实例应定义如下:

instance (CFunctor f, CFunctor g, Cod f ~ Dom g) => CFunctor (Wrap g f) where
  type Dom (Wrap g f) = Dom f
  type Cod (Wrap g f) = Cod g
  cmap f = cmap (cmap f)

但是,两次组合cmap会给出DOM f a b->Cod g(g(f a))(g(f b)),而CMap在这种情况下有一个类型DOM f a b->Cod g(Wrap g f a)(Wrap g f b)

我们可以从g(f)Wrap GF,反之亦然,但是由于实例声明没有对COD g的结构做出任何假设,所以我们运气不好。

由于我们知道functor是类别之间的映射,所以我们可以使用Cod g类别(在Haskell方面,这需要类别(Cod g)约束)这一事实,这给我们提供了很少的操作:

cmap f = lift? unWrap >>> cmap (cmap f) >>> lift? Wrap

但是,这需要一个方便的提升操作符lift?,它将函数从hask类别提升到cod g类别。将COD G写成(~>)Lift?的类型必须是:

lift? :: (a -> b) -> (a ~> b)

lift? unWrap  :: Wrap g f a ~> g (f a)
cmap (cmap f) :: g (f a)    ~> g (f b)
lift? Wrap    :: g (f b)    ~> Wrap g f b

lift? unWrap >>> cmap (cmap f) >>> lift? Wrap :: Wrap g f a ~> Wrap g f b

现在,对于这个起重操作员来说,至少有两种选择:

  • 您可以将constrait从类别(Cod g)扩展到箭头(Cod g),在这种情况下,举升操作员变为arr
  • 或者,正如Sjoerd Visscher在注释中提到的,您可以使用wrapunwrap在运行时语义上是ID,在这种情况下,unsafecoerce的使用是合理的。
 类似资料:
  • 我想在中的包中使用功能,它有一个需求,作为

  • 我想结合两个筛选函数来选择表中的几个元素。我的代码如下所示: 中的元素必须在第一个并且在一行中。因此,如果返回3个元素,它们必须在一行中,后面是中的元素。我怎样才能做到呢?我可以组合上面的筛选功能吗?

  • 我的问题是关于OOP(C)中的构造函数。当我在一个类中将默认构造函数定义为private,并且在main中将该类的一个对象初始化为default时,就会出现默认构造函数不可访问的错误。这很好。但我也在Public部分中使用默认参数构造函数,当我再次在main中初始化对象时,就会出现对函数重载的不明确调用。所以我的问题是,如果不能从main访问私有构造函数,那么编译器应该调用公共部分中的构造函数,这

  • 问题内容: 我试图编写登录到网站的节点功能,但无法使其正常工作。我试图等待页面使用加载功能 这是我到目前为止的内容: 当我运行该函数时,我收到错误消息。这是怎么回事,我想念什么? 问题答案: 为了与其他硒语言绑定的一致性, 并已被弃用。 如果您使用,则应尝试使用代替来确定元素是否存在,如下所示: 或者,如果您要等到欲望元素出现,则应尝试使用以下方法:

  • 我试图使用rxjs输入自动完成的目的,但我一直得到这些错误TypeError:terms.debounce时间不是一个函数,即使我设置这些导入'rxjs/操作员/DebounceTime'; 我称之为的函数是:

  • 在Angular2中尝试一个代码,它的HTML正在运行,但Angular代码没有执行,它表示我从HTML传递的值不是函数。请帮忙! HTML:app.html - 我正在尝试显示学生的详细信息。我在angular app.component.ts文件中有一个项目列表,我在HTML页面上调用它,工作正常。但是当我将单击事件的值传递给 app.component.ts 时,它会给出错误并在控制台上显示