JavaScript Array.map 通常是一个内函子还是只是一个函子?

Is JavaScript Array.map generally an endofunctor or just a functor?

  1. 函子是类别之间的结构保持转换。它是一种将对象从一个类别映射到另一类别的对象,同时还保留对象之间的箭头的某种方式——将其视为类别同态。

  2. 内函子是从一个类别回到同一类别的函子。

在JavaScript中,Array.map通常可以链接起来,因为它总是returns数组。

someArray
.map(f1) 
.map(f2) 
.map(f3)
...

所以,一开始,考虑到(2),我只是想"ok, since Array is a special type that has a method map, and it returns the same type, JavaScript array must be endofunctor."

但是,考虑到(1),我认为"wait, is it just a structure saving feature of all functors that is not limited to endofunctor?"

换句话说,"if it is chainable, it is an endofunctor"安全吗?或者它是无效的,因为 chainable map 和 endo- 是另一个概念?

是的,Array.map 是 javascript 中的内函子,因为它 return 通过使用对象作为自身来作为对象。注意,仅在 JS 中,因为它只使用 object.

在其他语言如 C# 中,当你定义一个数组时你需要给出包含的类型,它们之间的映射成为函子而不是内函子。

很容易识别。当且仅当 class 的函子总是 return 与其自身相同 class 时,此函子是一个内函子。

因此在 class MyClass,

a: function(){
   return this;
},
b: function(){
   return new MyClass();
}

那些是内函子。

但是,说可链式仿函数是端仿函数是不安全的。

简单地想象两个 class、class MyClassA()class MyClassB(),它们都有一个共享相同名称的仿函数(这很常见)。

MyClassA,

changetype: function(){
   return MyClassB;
}

反之亦然。

所以,一旦你能写出像

这样的东西
a = new MyClassA();
a.changetype().changetype().changetype()......

没有麻烦。

因此,如果您发现一个可链接的仿函数,您无法确定它是否是一个 endofunctor.As 共享同名仿函数在所有编程语言中都是非常非常典型的。

它是一个函子(或多或少),而不是一个内函子。

首先要意识到数学中的函子与编程中的函子不同,就像数学集合论中的 class 与 [=43= 不同一样] 在编程中。在编程中——特别是在 Haskell 中——Functor 是接口的名称。是的,一个接口。因为在Haskell中,一个类型class定义了一个接口,而Functor是一个类型class的名字,需要类型实现一个名为"fmap"的函数来满足Functor接口.

此处有更多详细信息:https://motts42.blogspot.com/2017/12/functors-according-to-haskell.html

Functor 类型class 看起来像这样,fmap :: (a -> b) -> f a -> f b。名称 "f"、"a" 和 "b" 都是变量 类型 。因此,例如,fmap 可能会将 Box Int 转换为 Box String,或将 List String 转换为 List Bool。容器类型,例如 Box 或 List,将 始终 相同,如 fmap 的签名中的类型变量 "f" 所示。唯一可以改变的部分是容器包含的类型。

Haskell 没有定义一个叫做endofunctor 的东西,所以现在我们不得不推测一下。毕竟,请记住 Haskell 仿函数是类型的接口,而不是类别之间的转换。在数学中,endofunctor 是将类别映射到自身的函子。在 Haskell 的 Functor 上下文中,我能解释的最好方法是 fmap 的类型变量 "a" 和 "b" 是相同类型的仿函数。也就是说,将 Box Int 映射到另一个 Box Int 或将 List String 映射到另一个 List String.

的 fmap 函数

对于 JavaScript 的数组,当然,您可以将一个数字数组映射到另一个数字数组,但您绝不仅限于这样做。您可以自由地将任何内容的数组映射到实际上任何其他内容的数组。