Math 为什么函子类没有返回函数?
从分类的角度来看,函子是两个映射对(一个在对象之间,另一个在类别的箭头之间),遵循一些公理 我假设,每个函子实例都类似于数学定义,即可以映射对象和函数,但Haskell的Math 为什么函子类没有返回函数?,math,haskell,monads,functor,category-theory,Math,Haskell,Monads,Functor,Category Theory,从分类的角度来看,函子是两个映射对(一个在对象之间,另一个在类别的箭头之间),遵循一些公理 我假设,每个函子实例都类似于数学定义,即可以映射对象和函数,但Haskell的函子类只有映射函数的functionfmap 为什么会这样 UPD换句话说: 每个Monad类型M都有一个函数return::a->ma 而函子类型F没有函数return::a->fa,只有fx构造函数。类别的对象与OO编程语言中的对象不同(我们更喜欢在Haskell中调用这些值;讨论了它们在类别理论中的含义)。相反,Hask的
函子
类只有映射函数的functionfmap
为什么会这样
UPD换句话说:
每个Monad类型M
都有一个函数return::a->ma
而函子类型F
没有函数return::a->fa
,只有fx
构造函数。类别的对象与OO编程语言中的对象不同(我们更喜欢在Haskell中调用这些值;讨论了它们在类别理论中的含义)。相反,Hask的对象是类型。Haskell函子
s是Hask中的内函子,即通过以下方式将类型关联到类型:
序曲>:k可能可能::*->*
序曲>:k Int
Int::*
序曲>:k可能是Int
也许是Int::* 当然,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
是对对象(即类型)的操作,对象的类型为T
,对象的类型为ft
,fmap
是对态射(即函数)的操作,对象的类型为fmap F::ft->fu
,首先,有两个级别:类型和值。由于Hask的对象是类型,因此只能使用类型构造函数对其进行映射,类型构造函数具有*->*
种类:
(对于α->Fα
)函子F
(对于β->Mβ
)李>单子M
fmap::(α->β)->(Fα->Fβ)
到目前为止,我想,我没有说什么新的。但重要的是Monad
的return::alpha->M alpha
并不是您可能认为的alpha
类型的映射器。关于单子的数学定义,return
对应于从Id
函子到M
函子的自然转换。只是这个Id
函子是隐式的。monad的标准定义还需要另一种自然转换M◦ M->M
。所以把它翻译成Haskell就像
class Functor m => Monad m where
return :: Id α -> m α
join :: m (m α) -> m α
(作为旁注:这两种自然变换实际上是单位和乘法,这使单子成为内函子范畴中的幺半群)
实际定义不同,但相同。看看这个
如果采用从标准bind派生的composition-like运算符=::mα->(α->mβ)->mβ:
(>=>) :: Monad m => (α -> m β) -> (β -> m γ) -> (α -> m γ)
f >=> g = \a => f a >>= g
你可以看到,这实际上都是关于。另请参见《计算机科学》中的关于单子的部分。尽管您在问题中使用了这些奇特的分类术语,并且应该对现有的答案感到完全满意,但这里尝试给出一个相当简单的解释: 假设在函子类型类中有一个函数
return
(或pure
或unit
或…
)
现在试着定义一些常见的Functor实例:[]
(列表),可能
,(,)a)
(带左组件的元组)
够简单的吧
以下是普通函子实例:
instance Functor [] where
fmap f (x : xs) = f x : fmap xs
fmap _ [] = []
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
instance Functor ((,) a) where
fmap f (x, y) = (x, f y)
现在如何处理函子的return
清单:
instance Functor [] where
return x = [x]
好的。也许吧
instance Functor Maybe where
return x = Just x
好的。现在是元组:
instance Functor ((,) a) where
return x = (??? , x)
您知道,不知道应该将哪个值填充到该元组的左侧组件中。实例声明说它有一个类型a
,但我们不知道该类型的值。可能类型a是只有一个值的单元
类型。但是如果它是Bool
,我们应该取True
还是False
?如果是Int Bool
我们应该取左0
还是右False
还是左1
因此,您可以看到,如果在functor上有一个return
,则通常无法定义许多有效的functor实例(您需要施加类似于FunctorEmpty类型类的约束)
如果您查看
Functor
和Monad
的文档,您将看到Functor((,)a)
确实有实例,但Monad(,)a)
没有实例。这是因为你不能为它定义return
。但是为什么没有特殊的函数,比如monad?你是什么意思?monad的情况也一样,每个monad类型M都有一个函数return::a->ma。但是functor类型F没有函数return::a->fa。但是它不会将对象映射到对象。用范畴论的术语来说,这是一个态射。是的,这就是我要说的。函子由两个态射组成,但在Haskell中,其中一个是简单函数,另一个是类型级实体。这不太正确。如果你想将函子视为态射,那么它只是一个:在类别类别中,对象是类别,类别a和类别B之间的态射是一个函子,它将a的对象映射到B的对象,以及a的态射映射到B的态射。在本例中,可能是哈斯克的内函子,例如,范畴范畴中的自同态,正如我所说的,它将对象映射到对象(例如,类型Int
到类型Maybe Int
),并将态射映射到态射(length::String->Int
到fmap length::Maybe String->Maybe Int