TypeScript 中的 Do-notation
Do-notation in TypeScript
我正在尝试找出一种方法来美化 TypeScript 中的单子库。虽然 monad 本身的实现进展顺利,但它的用法看起来像熟悉的回调地狱。
我想知道是否有办法劫持 async/await 或 yield/for..of 的现有 monadic 语法糖,但我必须承认我在连接这些点时遇到了一些麻烦。是否可以在既不是 Promise 也不是 Iterable 的东西上使用这些构造,并且与由反应组件组成的延续 monad 一样不同?
我的时间有限,但这里有一个使用 continuation monad Cont
作为示例的快速小示例
// first: WITHOUT do-notation
const Cont = f => ({
runCont: f,
chain: g =>
Cont(k => f (x => g (x) .runCont (k)))
})
Cont.of = x =>
Cont(k => k (x))
const result = Cont.of (2) .chain (x =>
Cont.of (3) .chain (y =>
Cont.of (x + y)))
result.runCont (console.log)
// 5
现在同样的事情使用了一种do
-notation——do
是JS中的保留关键字,所以我将我的函数命名为run
// second: WITH do-notation
const run = g => {
const next = x => {
let {value, done} = g.next (x)
return done
? value
: value.chain (next)
}
return next (null)
}
const Cont = f => ({
runCont: f,
chain: g =>
Cont(k => f (x => g (x) .runCont (k)))
})
Cont.of = x =>
Cont(k => k (x))
const result = run (function* () {
let x = yield Cont.of (2)
let y = yield Cont.of (3)
return Cont.of (x + y)
} ())
result.runCont (console.log)
// 5
警告: 你 可以 使用 async/await
但是你的值会卡在 Promises 中——这可能很烦人大多数情况下。
我正在尝试找出一种方法来美化 TypeScript 中的单子库。虽然 monad 本身的实现进展顺利,但它的用法看起来像熟悉的回调地狱。
我想知道是否有办法劫持 async/await 或 yield/for..of 的现有 monadic 语法糖,但我必须承认我在连接这些点时遇到了一些麻烦。是否可以在既不是 Promise 也不是 Iterable 的东西上使用这些构造,并且与由反应组件组成的延续 monad 一样不同?
我的时间有限,但这里有一个使用 continuation monad Cont
作为示例的快速小示例
// first: WITHOUT do-notation
const Cont = f => ({
runCont: f,
chain: g =>
Cont(k => f (x => g (x) .runCont (k)))
})
Cont.of = x =>
Cont(k => k (x))
const result = Cont.of (2) .chain (x =>
Cont.of (3) .chain (y =>
Cont.of (x + y)))
result.runCont (console.log)
// 5
现在同样的事情使用了一种do
-notation——do
是JS中的保留关键字,所以我将我的函数命名为run
// second: WITH do-notation
const run = g => {
const next = x => {
let {value, done} = g.next (x)
return done
? value
: value.chain (next)
}
return next (null)
}
const Cont = f => ({
runCont: f,
chain: g =>
Cont(k => f (x => g (x) .runCont (k)))
})
Cont.of = x =>
Cont(k => k (x))
const result = run (function* () {
let x = yield Cont.of (2)
let y = yield Cont.of (3)
return Cont.of (x + y)
} ())
result.runCont (console.log)
// 5
警告: 你 可以 使用 async/await
但是你的值会卡在 Promises 中——这可能很烦人大多数情况下。