Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math 为什么函子类没有返回函数?_Math_Haskell_Monads_Functor_Category Theory - Fatal编程技术网

Math 为什么函子类没有返回函数?

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的

从分类的角度来看,函子是两个映射对(一个在对象之间,另一个在类别的箭头之间),遵循一些公理

我假设,每个函子实例都类似于数学定义,即可以映射对象和函数,但Haskell的
函子
类只有映射函数的function
fmap

为什么会这样

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