Javascript 函子结合律

Javascript 函子结合律,javascript,haskell,monads,functor,associative,Javascript,Haskell,Monads,Functor,Associative,我被函子的结合定律弄糊涂了好几个星期了 我知道每一个内函子都形成合成/结合特征 构图是联想的。基本上,这意味着当你在编写多个函数时,如果你觉得有趣,你不需要括号: 让我们再看看JavaScript中的合成法则: 给定一个函子,F: 以下是等效的: 但是,如下代码所示,特别是后面的部分: console.log("==================="); const take1 = a => a //any .map(g) .map(f) .map(trace); 这将导致

我被函子的结合定律弄糊涂了好几个星期了

我知道每一个内函子都形成合成/结合特征

构图是联想的。基本上,这意味着当你在编写多个函数时,如果你觉得有趣,你不需要括号:

让我们再看看JavaScript中的合成法则:

给定一个函子,F:

以下是等效的:

但是,如下代码所示,特别是后面的部分:

console.log("===================");
const take1 = a => a //any
  .map(g)
  .map(f)
  .map(trace);
这将导致类型错误:

//  const r3 = v.map(take1); //TypeError: a.map is not a function
,当然:

const take2 = a => Identity(a) //Identity(any)
  .map(trace)
  .map(g)
  .map(trace)
  .map(f)
  .map(trace);
const r4 = v.map(take2);
工作

我觉得take2函数的错误之处在于,将参数类型:a转换为Identitya的要求并不是真正的组合函数

我也知道单子是为了避免这个构图问题,我想知道这个问题是否仅仅是因为单子缺少左右同一律,函子的结合律仍然满足,或者可能有不同层次的结合律,在函子中,某一层次的结合律显然满足,但另一层结合法则被打破,如上图所示

你能澄清一下吗

示例代码当然是用JavaScript编写的,但我仍然标记Haskell,因为社区在这个主题上很强大,所以请原谅

多谢各位

常量跟踪=x=>{ console.logx; 返回x; }; 常量标识=值=>{ map:fn=>identityfvalue, valueOf:=>value, }; 常数u=标识2; 常数f=n=>n+1; 常数g=n=>n*2; //合成律 常数r1=u .mapx=>fgx; 常数r2=u .mapg .mapf; r1.maptrace;//5. r2.maptrace;//5. console.log==============================; const take1=a=>a//any .mapg .mapf .maptrace; 常数v=Identity100; //常数r3=v.maptake1//TypeError:a.map不是函数 const take2=a=>Identitya//Identityany .maptrace .mapg .maptrace .mapf .maptrace; 常数r4=v.maptake2 当const r3=v.maptake1时,如果你已经进入了一层贴图,你可以输入函子。在函子内部,有纯的、未包装的值。但是take1本身试图再次对这些值使用map!这是可行的,但前提是这些值本身就是函子值——比如嵌套标识

要使用已在内部使用map的函数,只需将其应用于functor值:

常数f=n=>n+1; 常数g=n=>n*2; 常量标识=值=>{ map:fn=>identityfvalue, valueOf:=>value, }; const take1=a=>a//any .mapg .mapf; 常数v=Identity100; 常数r3=1V; console.logr3.valueOf 当const r3=v.maptake1时,如果你已经进入了一层贴图,你可以输入函子。在函子内部,有纯的、未包装的值。但是take1本身试图再次对这些值使用map!这是可行的,但前提是这些值本身就是函子值——比如嵌套标识

要使用已在内部使用map的函数,只需将其应用于functor值:

常数f=n=>n+1; 常数g=n=>n*2; 常量标识=值=>{ map:fn=>identityfvalue, valueOf:=>value, }; const take1=a=>a//any .mapg .mapf; 常数v=Identity100; 常数r3=1V;
console.logr3.valueOf 让我们试着整理一下术语

在范畴论中,C类由对象和态射(也称为箭头)组成。两类C和D之间的函子F,写为F:C->D,将C的对象映射到D的对象,将C的态射映射到D的态射

你可以用显而易见的方式组合函子

函子的合成是结合的:给定F:C->D,G:D->E和H:E->F,它们的合成是从C到F的函子,不需要括号

您还可以在类别内合成变形。态射的合成也是结合的

此外,函子必须尊重态射的合成,即Fg∘f=Fg∘Ff。这与关联性完全不同

内函子是从某个类别到同一类别的函子,F:C->C

在Javascript中,没有类型,因此要将其划分为一个类别,请将单个对象(某种通用类型)想象为唯一的对象。带变元的变元是一个函数

现在这个

const F = [1, 2, 3];
不是一个函子:你没有说对象是如何映射的,尽管没有太多的选择,你没有说变形Javascript函数是如何映射的

但是,您可以像这样为Javascript定义函子数组:

我们的通用类型映射到自身。如果Javascript有类型,我们将把类型t映射到类型t的类型数组

b通过逐点应用函数f,函数f从一个数组映射到一个数组。这是Javascript中数组的映射:Arrayf=x=>x.mapf使用=>for函数

请注意,数组不是可以完全用Javascript编写的任何东西

现在这个函子尊重compos 变形Javascript函数等的定义,这一点很容易理解。其中的一个中间步骤是,实际上x.mapf.mapg=x.mapy=>gfy非正式地说,首先将f应用于数组x的所有元素,然后将g应用于所有元素,或者在f之后立即将g应用于数组的所有元素,这并不重要

如果我们将它与其他functor组合在一起,它也将是关联的,尽管我们还没有Javascript中其他functor的示例

让我们暂时把monads排除在画面之外


这有用吗?

让我们试着整理一下术语

在范畴论中,C类由对象和态射(也称为箭头)组成。两类C和D之间的函子F,写为F:C->D,将C的对象映射到D的对象,将C的态射映射到D的态射

你可以用显而易见的方式组合函子

函子的合成是结合的:给定F:C->D,G:D->E和H:E->F,它们的合成是从C到F的函子,不需要括号

您还可以在类别内合成变形。态射的合成也是结合的

此外,函子必须尊重态射的合成,即Fg∘f=Fg∘Ff。这与关联性完全不同

内函子是从某个类别到同一类别的函子,F:C->C

在Javascript中,没有类型,因此要将其划分为一个类别,请将单个对象(某种通用类型)想象为唯一的对象。带变元的变元是一个函数

现在这个

const F = [1, 2, 3];
不是一个函子:你没有说对象是如何映射的,尽管没有太多的选择,你没有说变形Javascript函数是如何映射的

但是,您可以像这样为Javascript定义函子数组:

我们的通用类型映射到自身。如果Javascript有类型,我们将把类型t映射到类型t的类型数组

b通过逐点应用函数f,函数f从一个数组映射到一个数组。这是Javascript中数组的映射:Arrayf=x=>x.mapf使用=>for函数

请注意,数组不是可以完全用Javascript编写的任何东西

现在,这个函子考虑了态射、Javascript函数等的组合,这一点很容易理解。其中的一个中间步骤是,实际上x.mapf.mapg=x.mapy=>gfy非正式地说,首先将f应用于数组x的所有元素,然后将g应用于所有元素,或者在f之后立即将g应用于数组的所有元素,这并不重要

如果我们将它与其他functor组合在一起,它也将是关联的,尽管我们还没有Javascript中其他functor的示例

让我们暂时把monads排除在画面之外


这有帮助吗?

您所问的问题实际上与关联性定律无关。还有一个建议:为了完全进入函数思维,最好不要使用跟踪,而只显示最终值。并不是说Haskellers不使用跟踪进行调试,或者更确切地说,只是作为一种黑客来发现一些值差异细节。首先是类型检查阶段。你所问的问题实际上与关联性定律无关。还有一个建议:为了完全进入函数思维,最好不要使用跟踪,而只显示最终值。并不是说Haskellers不使用跟踪进行调试,或者更确切地说,只是作为一种黑客来发现一些值差异细节。首先是打字阶段。谢谢,但这是我所知道的,我想我在问题中已经澄清了。不幸的是,到目前为止,你没有回答任何关于这个话题的问题。嗯,你的问题是什么还不是很清楚。谢谢,但这就是我所知道的,我想我在问题中已经澄清了。不幸的是,到目前为止,你没有回答任何关于这个主题的问题。嗯,你的问题不是很清楚。“在Javascript中,值构成一个类别。”这没有意义,是吗?类别中应该包含哪些值?它们当然不是这个类别的对象。@leftaroundabout:你说得对,我很困惑,因为没有类型。“在Javascript中,值构成一个类别。”这没有意义,是吗?类别中应该包含哪些值?它们当然不是这个类别的对象。@leftaroundabout:你说得对,我很困惑,因为没有类型。编辑。
const take2 = a => Identity(a) //Identity(any)
  .map(trace)
  .map(g)
  .map(trace)
  .map(f)
  .map(trace);
const r4 = v.map(take2);
const F = [1, 2, 3];