为什么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 。
