javascript – 为什么Promises Monads?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 为什么Promises Monads?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4469字,纯文字阅读大概需要7分钟。
内容图文
![javascript – 为什么Promises Monads?](/upload/InfoBanner/zyjiaocheng/712/24e84b08522e4ca2933a5ca2e62377ae.jpg)
我一直在学习函数式编程,并且遇到了Monads,Functors和Applicatives.
根据我的理解,以下定义适用:
a)(A => B)=> C [A] => C [B] |函子
b)(A => C [B])=> C [A] => C [B] |单子
c)(C [A => B])=> C [A] => C [B] |合用的
(参考:https://thedet.wordpress.com/2012/04/28/functors-monads-applicatives-can-be-so-simple/)
此外,我了解Monad是Functor的一个特例.在中,它应用一个函数,该函数将包装值返回到包装值并返回包装值.
当我们使用Promise.then(func)时,我们传递Promise(即C [A])一个通常具有签名A =>的函数. B并返回另一个Promise(即C [B]).所以我的想法是,Promise只是一个Functor而不是Monad,因为func返回B而不是C [B].
然而,谷歌搜索我发现Promise不仅是一个Functor,也是一个Monad.我想知道为什么,因为func没有返回包裹值C [B]而只是B.我错过了什么?
解决方法:
UDATE.
看到这个新图书馆
证明函子和monad运算符
用于基于回调的普通函数
那些没有问题的问题
如下所述:
https://github.com/dmitriz/cpsfy
JS Promise既不是Functor也不是Applicative,也不是Monad
它不是一个算符,因为
composition preservation law
(将函数组合发送到其图像的合成)
被违反:
promise.then(x => g(f(x)))
不等同于
promise.then(f).then(g)
这实际上意味着什么,
重构永远不会安全
promise
.then(x => f(x))
.then(y => g(y))
至
promise
.then(x => g(f(x))
就像它本来一样,Promise是一个仿函数.
函子违法行为的证明.这是一个反例:
//Functor composition preservation law: // promise.then(f).then(g) vs promise.then(x => g(f(x))) // f takes function `x` // and saves it in object under `then` prop: const f = x => ({then: x}) // g returns the `then` prop from object const g = obj => obj.then // h = compose(g, f) is the identity const h = x => g(f(x)) // fulfill promise with the identity function const promise = Promise.resolve(a => a) // this promise is fulfilled with the identity function promise.then(h) .then(res => { console.log("then(h) returns: ", res) }) // => "then(h) returns: " a => a // but this promise is never fulfilled promise.then(f) .then(g) .then(res => { console.log("then(f).then(g) returns: ", res) }) // => ??? // because this one isn't: promise.then(f) .then(res => { console.log("then(f) returns: ", res) })
这是Codepen上的这个例子:
https://codepen.io/dmitriz/pen/QrMawp?editors=0011
说明
由于组合h是身份函数,所以promise.then(h)简单地采用了承诺的状态,其已经用身份a =>来实现.一个.
另一方面,f返回所谓的thenable:
1.2. “thenable” is an object or function that defines a then method.
为了维护仿函数法则,然后必须简单地将结果f(x)包含在承诺中.相反,当.then中的函数返回“thenable”时,Promise Spec需要不同的行为.根据2.3.3.3,身份功能id = a =>存储在then键下的一个被称为
id(resolvePromise, rejectPromise)
其中resolvePromise和rejectPromise是promise解析过程提供的两个回调函数.但是,为了得到解决或拒绝,必须调用其中一个回调函数,这些函数永远不会发生!因此,由此产生的承诺仍处于待决状态.
结论
在这个例子中,
promise.then(x => g(f(x)))
用身份函数a =>来实现一个,
而
promise.then(F).然后(G)
永远处于待定状态.
因此,这两个承诺并不相同
因此违反了仿函法.
承诺既不是Monad也不是Applicative
因为即使是Pointed Functor规范中的自然变换定律,即Applicative(同态定律)的一部分,也被违反:
Promise.resolve(g(x)) is NOT equivalent to Promise.resolve(x).then(g)
证明.这是一个反例:
// identity function saved under `then` prop const v = ({then: a => a}) // `g` returns `then` prop from object const g = obj => obj.then // `g(v)` is the identity function Promise.resolve(g(v)).then(res => { console.log("resolve(g(v)) returns: ", res) }) // => "resolve(g(v)) returns: " a => a // `v` is unwrapped into promise that remains pending forever // as it never calls any of the callbacks Promise.resolve(v).then(g).then(res => { console.log("resolve(v).then(g) returns: ", res) }) // => ???
Codepen上的这个例子:https://codepen.io/dmitriz/pen/wjqyjY?editors=0011
结论
在这个例子中,一个承诺得以实现,而另一个承诺未决,因此这两个在任何意义上都不相同,违反了法律.
UPDATE.
究竟“成为一个Functor”是什么意思?
Promise作为Functor / Applicative / Monad之间似乎存在混淆,以及通过改变方法或添加新方法来实现这一点的方式.但是,Functor必须具有已经提供的map方法(不一定以此名称),并且作为Functor显然取决于此方法的选择.只要法律得到满足,方法的实际名称就不起任何作用.
对于Promises,.then是最自然的选择,它不符合下面解释的Functor定律.据我所知,其他Promise方法都没有以任何可能的方式使它成为Functor.
更改或添加方法
是否可以定义符合法律的其他方法是另一回事.我所知道的这个方向的唯一实现是由creed library提供的.
但是需要付出相当大的代价:不仅需要定义全新的map方法,而且还需要更改promise对象本身:信条承诺可以保持“有效”作为价值,而原生JS承诺可以’吨.这种变化是实质性的,并且必须避免违反实施例中的法律,如下所述.特别是,我没有任何方法将Promise变成Functor(或Monad)而没有这些根本性的变化.
内容总结
以上是互联网集市为您收集整理的javascript – 为什么Promises Monads?全部内容,希望文章能够帮你解决javascript – 为什么Promises Monads?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。