5 javascript monads haskell promise es6-promise
我知道 Javascript 的承诺在技术上既不是 Haskell 意义上的函子也不是 monad,因为(除其他外)
bind
回退到map
传入纯函数时的操作(因此具有不明确的类型)Promise
函数和resolve
(又名return
)递归地连接嵌套的 Promise通过始终提供具有正确类型的函数,可以轻松绕过第一个问题a -> Promise b
。
第二个问题显然违反了参数多态函数的参数性特征,即无法构造结构m (m a)
。但是这个结构在承诺/异步计算的上下文中意味着什么?我想不出Promise (Promise a)
, wherePromise
是 monad 的有意义的语义。那么我们会失去什么呢?递归连接的含义是什么?
假设我们非常务实(这就是我们在编写 Javascript 时应该做到的),Promise
如果我们考虑到边缘情况,我们不能声称 a 是 Javascript 中的 monad 吗?
通过始终提供具有正确类型的函数,可以轻松绕过第一个问题
a -> Promise a
。
或者不使用monad 的操作,而是使用一些类型正确的操作then
。Creed是一个功能性的 Promise 库,它提供了实现代数类型的Fantasy-land规范的方法。bind
map
chain
第二个问题也可以通过相同的方法来绕过,即不使用resolve
而是fulfill
使用静态of
方法作为单元函数。
但是这个结构在承诺/异步计算的上下文中意味着什么?
这是对价值的承诺。并非每个可构造类型都需要“有意义”或“有用”:-)
然而, Fetch API提供了一个类似类型的好例子:它返回一个解析为Response
对象的 Promise,该对象又“包含”一个解析为响应正文的 Promise。
因此 aPromise (Promise a)
可能只有一个成功结果值,也可以通过 a 访问Promise a
,但是两层承诺
请注意,出于拒绝原因,该Promise
类型应该有第二个类型变量,类似于Either
. 两级Promise err1 (Promise err2 a)
与Promise err a
.
我知道 Javascript 的承诺在技术上既不是 Haskell 意义上的函子也不是 monad
然而,您还没有提到最大的问题:它们是可变的。如果我们考虑执行顺序,从挂起状态到已解决状态的转换是一个副作用,它会破坏引用透明度,当然,我们通常的 Promise 用例涉及大量根本不是由 Promise 类型建模的 IO。
Promise.delay(50).then(() => Promise.delay(50))
// does something different than
const a = Promise.delay(50); a.then(() => a)
Run Code Online (Sandbox Code Playgroud)
应用单子定律很有趣,有时也很有用,但我们确实需要大量的实用主义。
归档时间: |
|
查看次数: |
1287 次 |
最近记录: |