Haskell 确切地说是什么意思;“函子中的函数”;

Haskell 确切地说是什么意思;“函子中的函数”;,haskell,category-theory,Haskell,Category Theory,在范畴论中,函子是两个范畴之间的同态。在Haskell中,据说应用函子允许我们“在函子内部”应用函数。有人能把“函子中的函数”这个词翻译回数学,或者给出一些其他的见解吗?(我知道functor可能是,[]等,但仍然难以理解这个概念。)我的范畴理论一点也不强(我从Haskell的编程方面开始,最近一直在尝试学习它的一些概念的范畴理论基础)。但我得到的是: 在Haskell中,函子是类型构造函数,这意味着它从一般类型映射到“函子中的类型” 在范畴论中,函子从一个范畴的对象映射到另一个范畴的对象 当将

在范畴论中,函子是两个范畴之间的同态。在Haskell中,据说应用函子允许我们“在函子内部”应用函数。有人能把“函子中的函数”这个词翻译回数学,或者给出一些其他的见解吗?(我知道functor可能是
[]
等,但仍然难以理解这个概念。)

我的范畴理论一点也不强(我从Haskell的编程方面开始,最近一直在尝试学习它的一些概念的范畴理论基础)。但我得到的是:

在Haskell中,函子是类型构造函数,这意味着它从一般类型映射到“函子中的类型”

在范畴论中,函子从一个范畴的对象映射到另一个范畴的对象

当将范畴理论应用于Haskell时,我们想象我们正在处理范畴Hask,Haskell类型的范畴

所以Haskell函子不是一般的范畴论函子;它们都从Hask映射到Hask的一个子类(因为某些函子
f
和任意类型
a
的类型仍然是Haskell类型)。例如,
Maybe
函子将Hask中的对象(类型)映射到表单
Maybe a
的类型类别

函数在Haskell中是一流的,因此函数类型是非常普通的类型(并且是Hask的对象),所以函子也将函数类型映射到“函子中的函数类型”。所以短语“函子中的函数”是将函子应用于函数类型而产生的类型中的值的缩写。e、 g.
Just(+1)
是类型
Maybe(Int->Int)
中的一个特定值,它是
Maybe
functor将对象映射到的对象(类型)

所以“applicative functor”是一个具有一些额外规则的functor,这些规则足以获取类型中的函数值,这些类型是functor“destination”类别的对象,并将这些值应用于destination类别中类型中的其他值

再次以
Maybe
为例,如果我们只知道它是一个函子,它给了我们对象
Int->Char
Maybe(Int->Char)
之间的对应关系,对象
Int
Maybe Int
之间的对应关系,以及对象
Char
Maybe Char
之间的对应关系。但是,虽然我们有能力在
Int->Char
中获取一个值,在
Int
中获取一个值,并在
Char
中生成一个值,
Maybe
作为一个函子,并不保证我们有能力对
Maybe(Int->Char)中的值执行相应的操作
中的值可能是Int

当我们也知道它是一个应用函子时,我们确实有能力在
Maybe(Int->Char)
中取一个值,在
Maybe Int
中取一个值,并在
Maybe Char
中生成一个值,这满足了
Int->Char
值应用于
Int
值时的某些属性


据我所知,从纯范畴理论的角度来看,应用函子并不十分有趣。也许这是因为范畴理论关注对象之间的关系,它们对应于Haskell中的类型,但是从编程的角度来看,应用函子是由这些类型中的值之间的关系驱动的?(我们希望通过使用函子获得的“函数类型”中的值仍然能够应用于计算中)。

转换回数学

在一个封闭的幺半群范畴中,有一个“指数”的概念,它将态射关系“内在化”。然后可以计算这些指数。也就是说,你有一种说法(请原谅我的想法,Stackoverflow缺少mathjax)

以及咖喱和未咖喱的元操作。
“应用函子”以“适用”的方式映射指数,
F(a~>b)
可以与
fa
组合,得到
fb
。这是因为应用函子是幺半函子,所以它们有一个操作(在目标类别中)

当您同时进行fmap评估时,Haskell会向您提供
ap

我怀疑这是否有用

哈斯克尔家族

理解应用函子的最佳方法是查看类型

class Functor f => Applicative f where
  pure :: a -> f a
  <*>  :: f (a -> b) -> f a -> f b
一个更有趣的例子是无限序列

data Seq a = Seq a (Seq a)
instance Applicative Seq where
  pure a = Seq a (pure a)
  (Seq f fs) <*> (Seq x xs) = Seq (f x) (fs <$> xs)
数据顺序a=顺序a(顺序a)
实例应用程序Seq where
纯a=序列a(纯a)
(序列f fs)(序列x x x)=序列(f x)(序列x)

您可以认为这相当于列表上的$
zipWith。所有的
Monad
s都是
Applicative
,但我认为无限序列很有趣,因为对应的Monad实例……不明显(而且相当慢)。这将作为一个练习留给读者(顺便说一句,我正在从我记得读过的一些东西中学习这个例子/练习,我认为是pigworker在这个网站上写的)

相关:(在这里我仍然没有我的问题的答案,但应用的数学本质被触动了不少)@leftaroundabout极好,而且是关于类似主题的更高级的问题。感谢您的链接。查看应用程序函子
()
的“关键组件”类型是否有帮助(
applicative f=>f(a->b)->f a->f b
),或者您是否在寻找比这更“深刻”的东西?在
applicative
的定义中,不应该在那里而不是在那里吗?我知道我参加聚会要迟到了,但不应该在那里评估:(a ~>b,a)->a是
评估:(a ~>b,a)->b
?@raichoo。固定的
class Functor f => Applicative f where
  pure :: a -> f a
  <*>  :: f (a -> b) -> f a -> f b
newtype Id a = Id a
instance Applicative Id where
  pure a = Id a
  Id f <*> Id a = Id (f $ a)
pure = return
mf <*> mx = do f <- mf
               x <- mx
               return (f x)
data Seq a = Seq a (Seq a)
instance Applicative Seq where
  pure a = Seq a (pure a)
  (Seq f fs) <*> (Seq x xs) = Seq (f x) (fs <$> xs)