为什么Promises Monads? [英] Why are Promises Monads?

查看:146
本文介绍了为什么Promises Monads?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在学习函数式编程,并遇到过Monads,Functors和Applicatives。

I've been learning about functional programming and have come across Monads, Functors and Applicatives.

根据我的理解,以下定义适用:

From my understanding the following definitions apply:

a)(A => B)=> C [ A] => C [B] | Functor

a) ( A=>B ) => C[A] => C[B] | Functor

b)(A => C [B])=> C [A] => C [B] | Monad

b) ( A=>C[B] ) => C[A] => C[B] | Monad

c)(C [A => B])=> C [A] => C [B] |适用

c) ( C[A=>B] ) => C[A] => C[B] | Applicative

(参考: https://thedet.wordpress.com/2012/04/28/functors-monads-applicatives-can-be-so-simple/

此外,我了解Monad是Functor的一个特例。在中,它将函数应用于包装值,并返回包装值。

Furthermore, I understand a Monad is a special case of a Functor. As in, it applies a function that returns a wrapped value to a wrapped value and returns a wrapped value.

当我们使用 Promise.then(func)时,我们传递的是Promise(即C [A])通常具有签名的函数 A => B 并返回另一个Promise(即C [B])。所以我的想法是,Promise只是一个Functor而不是Monad,因为 func 返回B而不是C [B]。

When we use Promise.then(func), we are passing the Promise(i.e. C[A]) a function which normally has signature A => B and return another Promise (i.e. C[B]). So my thinking was that a Promise would only be a Functor and not a Monad as func returns B and not C[B].

然而,谷歌搜索我发现Promise不仅是一个Functor,而且还是一个Monad。我想知道为什么,因为 func 没有返回包裹值C [B]但只返回B.我缺少什么?

However, googling I found out that a Promise is not only a Functor, but also a Monad. I wonder why, as func does not return a wrapped value C[B] but just B. What am I missing?

推荐答案

Promise既不是Functor也不是Applicative,也不是Monad



它不是一个仿函数,因为作文保存法
(发送功能组合他们的图像的组成)
被违反:

Promise is neither a Functor nor an Applicative nor a Monad

It is not a functor, because the composition preservation law (sending compositions of functions to compositions of their images) is violated:

promise.then(x => g(f(x))) is NOT equivalent to promise.then(f).then(g)

这意味着什么实际上,
重构永远不会安全

What this means in practical terms, it is never safe to refactor

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

Here is this example on Codepen: https://codepen.io/dmitriz/pen/QrMawp?editors=0011

由于作文 h 是身份函数, promise.then(h)只是采用 promise 的状态,已经用身份 a =>来实现。 a

Since the composition h is the identity function, promise.then(h) simply adopts the state of promise, which is already fulfilled with the identity a => a.

另一方面, f 返回所谓的 thenable

On the other hand, f returns the so-called thenable:


1.2。 thenable是定义then方法的对象或函数。

1.2. "thenable" is an object or function that defines a then method.

为了维护仿函数法,。然后必须简单地包装成承诺结果 f(x)。相反,当 .then Promise Spec 需要不同的行为。 c>返回thenable。根据 2.3.3.3 ,身份函数 id = a => a 存储在下,然后键被称为

To uphold the functor law, .then would have to simply wrap into promise the result f(x). Instead, the Promise Spec requires a different behavior when the function inside .then returns a "thenable". As per 2.3.3.3, the identity function id = a => a stored under then key is called as

id(resolvePromise, rejectPromise)

其中 resolvePromise rejectPromise 是promise解析过程提供的两个回调函数。但是,为了得到解决或拒绝,必须调用其中一个回调函数,这些函数永远不会发生!因此,由此产生的承诺仍处于暂挂状态。

where resolvePromise and rejectPromise are two callback functions provided by the promise resolution procedure. But then, in order to be resolved or rejected, one of these callback functions must be called, which never happens! So the resulting promise remains in the pending state.

在此示例中,
promise.then(x => g(f(x)))
符合身份函数 a => a

promise.then(f).then(g)
仍在待定永远的状态。
因此这两个承诺不等于
,因此违反了仿函法。

In this example, promise.then(x => g(f(x))) is fulfilled with the identity function a => a, whereas promise.then(f).then(g) remains in the pending state forever. Hence these two promises are not equivalent and therefore the functor law is violated.

因为即使是来自 Pointed Functor的自然转换法规范,是 Applicative

Because even the natural transform law from the Pointed Functor Spec, that is part of being Applicative (the homomorphism law), is violated:

Promise.resolve(g(x)) is NOT equivalent to Promise.resolve(x).then(g)

证明。这是一个柜台-example:

Proof. Here is a counter-example:


// identity function saved under `then` prop
const v = ({then: a => a})

// `g` returns the `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

This example on Codepen: https://codepen.io/dmitriz/pen/wjqyjY?editors=0011

在这个例子中,一个承诺得到满足,而另一个承诺正在等待,因此这两个在任何意义上都不相同,违反了法律。

In this example again one promise is fulfilled, whereas the other is pending, therefore the two are not equivalent in any sense, violating the law.

这篇关于为什么Promises Monads?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆