Javascript 函子结合律
我被函子的结合定律弄糊涂了好几个星期了 我知道每一个内函子都形成合成/结合特征 构图是联想的。基本上,这意味着当你在编写多个函数时,如果你觉得有趣,你不需要括号: 让我们再看看JavaScript中的合成法则: 给定一个函子,F: 以下是等效的: 但是,如下代码所示,特别是后面的部分: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); 这将导致
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];