【发布时间】:2019-04-15 13:53:55
【问题描述】:
我仍然掌握函数式编程的窍门,并试图找出 Monads 的一个小问题。我有一种情况,我有一个未来会发出一个 HTTP 请求并返回一个值列表,为了参数的缘故。然后我希望能够检查该列表中是否存在特定值,我会认为在这里返回一个 Maybe monad 会是胜利。但是,如果该值存在,我希望能够基于该返回值发出另一个 HTTP 请求,但它应该仅在该值存在时运行。这是一个使用 Future & Maybe https://codesandbox.io/s/2xvy3m1qmy 的 ramda-fantasy 实现的示例
我很可能把这整件事弄错了,所以如果您需要更多信息,或者需要更改上述任何内容,那就去做吧。只是为了澄清这将是我在伪代码中的工作流程:
- 请求所有值
- 过滤值并可能找到匹配的值
- 如果找到,请求获取其余数据
这是一个初步的、带注释的尝试,如上链接所示:
import R from "ramda";
import Fantasy from "ramda-fantasy";
const Future = Fantasy.Future;
const Maybe = Fantasy.Maybe;
// make a fake HTTP request and return a list of values
// response :: Future Array String
const response = Future.of(['one', 'two', 'three'])
const maybeOrNothing = val => val ? Maybe.Just(val) : Maybe.Nothing()
// Maybe return our given value
// getVal :: String -> Maybe String
const getVal = input => response.map(R.find(R.equals(input))).map(maybeOrNothing)
// make another fake request
// let's pretend that this takes an ID and makes a fake ajax request to get teh data
// getValueData :: String -> Future
const getValueData = id => Future((reject, resolve) => {
// fake HTTP request
setTimeout(() => {
resolve({
id: id,
foo: 'bar'
})
}, 100)
})
// 'one' should then run getValueData
// something isn't right here, do I need to map then chain?
getVal('one')
.chain(getValueData)
.fork(console.error, console.log)
// 'five' isn't there, so shouldn't run getValueData
// something isn't right here as getValueData still runs
// map(R.chain) works to not run getValueData but then it causes issues later on
getVal('five')
.chain(getValueData)
.fork(console.error, console.log)
【问题讨论】:
-
请在您的问题中发布代码本身,而不仅仅是指向它的链接。
-
已更新以在帖子中包含代码
-
getVal的类型应该是String -> Future (Maybe String),对吧?
标签: javascript functional-programming monads