为什么Functor类没有返回函数?
从分类角度来看,仿函数是一对两个地图(一个在对象之间,另一个在类别的箭头之间),遵循一些公理。
我假设,每个Functor实例与数学定义类似,即可以映射对象和函数,但Haskell的Functor
类只有映射函数的函数fmap
。
为什么这样?
UPD换句话说:
每个Monad类型M
都有一个函数return :: a -> M a
。
Functor类型F
没有函数return :: a -> F a
,但只有F x
构造函数。
首先,有两个层次:类型和值。 由于Hask的对象是类型,所以只能将它们映射到具有* -> *
类型的类型构造函数:
α -> F α
Functor F
(对于Functor F
), β -> M β
Monad M
(对于Monad M
)。 然后对于一个fmap :: (α -> β) -> (F α -> F β)
函数,你需要一个态射映射(即函数,它们是值):它只是fmap :: (α -> β) -> (F α -> F β)
。
到目前为止,我猜,我没有说任何新的东西。 但重要的是, Monad
return :: α -> M α
Monad
并不像您想象的那样是一个到M α
的类型α
的映射器。 关于monad的数学定义, return
对应于从Id
仿函数到M
仿函数的自然变换 。 只是这个Id
函数是隐含的。 monad的标准定义还需要另一个自然变换M ◦ M -> M
所以把它翻译成Haskell就好
class Functor m => Monad m where
return :: Id α -> m α
join :: m (m α) -> m α
(作为一个侧面说明:这两种自然变化实际上是单位和乘法,这使得monad成为endofunctors类别中的幺半群)
实际的定义不同,但是是等价的(除非上下文中缺少Functor
实例)。 请参阅Haskell / wiki。
如果您从标准绑定>>= :: m α -> (α -> m β) -> m β
:
(>=>) :: Monad m => (α -> m β) -> (β -> m γ) -> (α -> m γ)
f >=> g = a => f a >>= g
你可以看到,这其实都是关于Kleisli类别的。 另请参阅nLab关于计算机科学中monad的文章。
类别的对象与面向对象编程语言中的对象不同(我们更喜欢在Haskell中调用这些值;这里讨论了它们在类别理论中的含义)。 Hask的对象是类型。 Haskell Functor
s是Hask中的endofunctors ,即将类型关联到类型,方法如下:
前奏>:k也许吧
也许:: * - > *
Prelude>:k Int
Int :: *
前奏>:k也许诠释
也许Int :: *
OTOH, Hask的箭头实际上是一些函数类型a -> b
。 这些关联如下:
fmap :: ( Functor (f :: t -> f t {- type-level -} ) )
=> (a->b) -> fmap(a->b) {- value-level -}
≡ (a->b) -> (f a->f b)
如果你有
instance Functor F where
fmap = ...
然后类型构造函数F
是对FT
类型采用类型T
对象(它是类型)的动作,而fmap
是对态射函数(它是函数)采取函数f :: T -> U
对fmap f :: FT -> FU
。