我有点困惑,需要有人帮我。让我们概述一下我目前的理解:
E
是一个endofunctor,A
是某个类别:
E : A -> A.
由于Haskell中的所有类型和态射都在Hask
类别中,Haskell中的任何仿函数也不是 endofunctor ? F : Hask -> Hask
。
我有一种很好的感觉,我错了,并且以某种方式过度简化了这一点,我希望有人告诉我,我是一个多么的白痴。感谢。
答案 0 :(得分:34)
您可能想澄清一下您是在询问“Haskell中的函子”还是Functor
。在Haskell中使用类别理论术语时,并不总是清楚假设什么类别。
但是,是的,默认假设是 Hask ,它被认为是具有函数作为态射的Haskell类型的类别。在这种情况下, Hask 上的endofunctor F会将任何类型A映射到类型F(A),并将两种类型A和B之间的任何函数 f 映射到函数F(某些类型F(A)和F(B)之间的 f 。
如果我们将自己仅限于那些将任何类型a
映射到(f a)
类型的endofunctors,其中f
是类型* -> *
的类型构造函数,那么我们就可以将函数的关联映射描述为类型为(a -> b) -> (f a -> f b)
的高阶函数,这当然是名为Functor
的类型类。
然而,可以很容易地想象 Hask 上表现良好的endofunctor,它们不能(直接)作为Functor
的实例编写,例如映射类型{{的仿函数1}}到a
。虽然从 Hask 到其他类别的仿函数显然没有太多意义,但从 Hask 到 Hask 考虑一个(逆变)仿函数是合理的强> 运算
除此之外,Either a t
的实例必须从整个类别 Hask 映射到它的某个子集,因此也会形成一个类别。但是,在 Hask 的子集之间讨论算子也是合理的。例如,考虑一个将Functor
类型发送到Maybe a
的仿函数。
您可能希望仔细阅读category-extras
package,它提供了嵌入 Hask 中的一些类别理论启发的结构,而不是假设其全部。
答案 1 :(得分:14)
即使最终你操纵Hask
,也可以在Hask
上构建许多其他类别,这对于手头的问题有意义:
Hask
^ op,Hask
所有箭头都反转Hask * Hask
,其上的仿函数是 bifunctors a
的态射,态射是可交换的三角形获取Mac Lane的工作数学家的类别的副本以获得定义,并尝试自己找到他们在Haskell中解决的问题。尤其是伴随仿函数(它们是正确类别中的初始/终端对象)以及它们与monad的关系。
你会看到即使有一个大类别(Hask
,或者可能是“使用正确的箭头/产品/ ......从Hask
中提升对象”,它封装了语言选择对于Haskell,例如非严格和懒惰),适当的派生类别是富有表现力的。
答案 2 :(得分:7)
关于monad的一个可能相关(或至少是有趣的)讨论可以在“Monads need not be endofunctors”一文中找到: