javascript - Fluture bimap 和 fold,有什么区别,我应该什么时候使用它们?

标签 javascript functional-programming future fluture

背景

我正在使用 Fluture抽象 future 。

假设我有一个发出 GET 请求的函数。此功能可能成功或失败。

发出请求后,如果成功,则打印一条消息,如果失败,则记录错误并执行命令。

axios.get(endpoint, { timeout: timeoutMs })
    .fold(
        err =>
            logger.errorAsync( err )
            .chain( ( ) => cmd.getAsync("pm2 restart app")),
        response => logger.infoAsync( "Great success!" )
    );

研究

我一直在阅读 API,我发现 bimapfold 都对成功和错误应用了一个函数:

bimap:将左函数映射到拒绝值,或将右函数映射到分辨率值,具体取决于存在哪个。

fold:将左函数应用于拒绝值,或将右函数应用于分辨率值,具体取决于哪个函数存在,并用结果进行解析。

问题

如果您有敏锐的眼光,就会知道我的示例行不通。我需要使用 bimap,但我不明白为什么。

问题

  1. 什么时候应该使用bimap,什么时候应该使用fold
  2. 它们之间的主要区别是什么?

最佳答案

让我们首先检查一下它们各自的类型签名:

bimap :: (a -> c) -> (b -> d) -> Future a b -> Future c d
fold  :: (a -> c) -> (b -> c) -> Future a b -> Future d c

差异非常细微,但显而易见。有两个主要区别:

  1. 第二个参数的返回值不同:在bimap中,两者 允许函数返回不同的类型。在 fold 中,两个函数 必须返回相同类型的值。
  2. 最终的返回值是不同的:在 bimap 中,你得到一个 Future where 拒绝包含从左函数返回的类型的值, 并且分辨率包含从右侧返回的类型的值 功能。在 fold 中,拒绝端包含一个全新的类型变量,它 尚未受到限制,决议方包含的值(value) both 函数返回的类型。

这太啰嗦了,可能有点难以解析。我将尝试在图表中将其可视化。

对于bimap,它看起来像下面这样。这两个分支不交互:

             rej(x)  res(y)
                 |       |
                 |       |
bimap(f)(g):   f(x)    g(y)
                 |       |
                 V       V

对于 fold,拒绝分支会“停止”,而解决分支会 继续 f(x) 的返回值 g(y) 的返回值:

             rej(x)  res(y)
                 |       |
                 |       |
fold(f)(g):      ->  f(x)*g(y)
                         |
                         V

您可以随时使用bimap 更改拒绝原因和 同时分辨率值。做 bimap (f) (g) 就像做 撰写 (mapRej (f)) (map (g))

只要你想将拒绝移动到解决方案中,就可以使用 fold 分支。在您的情况下,这就是您想要的。你的例子没有的原因 工作是因为你最终得到了一个 future 的 future ,你必须 展平:

axios.get(endpoint, { timeout: timeoutMs })
    .fold(
        err =>
            logger.errorAsync( err )
            .chain( ( ) => cmd.getAsync("pm2 restart app")),
        response => logger.infoAsync( "Great success!" )
    )
    .chain(inner => inner); //<-- Flatten

扁平化 Monad 在函数式编程中很常见,通常是 称为 join,可以像这样实现:

const join = chain(x => x)

关于javascript - Fluture bimap 和 fold,有什么区别,我应该什么时候使用它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51426121/

相关文章:

javascript - 如何使用 ES5 原型(prototype)重构类表达式?

javascript - 切换 CSS 类的纯 Javascript 替代方案?

list - 如何从haskell中的列表中提取最大元素?

java - 关于如何并行化此处理的想法(Java 8 功能)?

scala - 在 Scala 中顺序组合任意数量的 future

scala - 斯卡拉 future : possible to find out if an 'onFailure' callback has been installed (so we can implement default error handling)?

javascript - Jquery .val() 不会更改 ui-autocomplete 选择处理程序上的任何内容

javascript - 如何在 Highcharts 中保持 x 轴最大值不变?

javascript - 合并两个具有交替值的数组

java - 在 Java 8 中组合函数和谓词