【问题标题】:Name and existence of functor or monad to chain and terminate sequence of operations用于链接和终止操作序列的函子或单子的名称和存在
【发布时间】:2016-03-19 05:32:15
【问题描述】:

请原谅我,我会尽力描述我在寻找什么。我没有它的名字,所以它使它变得更加困难。

查看诸如 Folktalemonet.js 之类的库,我喜欢能够使用 map 链接操作而无需空检查或 if 语句,例如使用Maybe, Either, Task.

我想知道是否存在类似的构造来解决以下问题:

  • 我有一个初始输入。
  • 我想构造一个对输入进行操作的函数链。
  • 每个函数可能会或可能不会返回结果。
  • 如果函数没有返回结果,则调用链中的下一个函数。
  • 一旦函数返回结果,忽略链中的其余函数(类似于mapping Maybe.Nothing 上的函数)
  • 返回结果。

换句话说,我正在寻找类似于Maybe 的东西,它保存一个值并将函数映射到Just,但忽略映射到Nothing 的函数,您可以提取该值。我正在寻找包含输入和初始null 结果的东西。当您 map 一个函数时,只有当 result 为空时,它才会在输入上运行该函数。如果函数返回一个值,则该值将成为结果,并且任何其他映射的函数都将被忽略。最后,您可以提取结果。

在命令式编程中,这可能看起来像:

var result1 = function1(input);
if (result1) {
  return result1;
}
var result2 = function2(input);
if (result2) {
  return result2;
}
// and so on.

相反,我想按照以下方式构建一些东西

Something(input).map(function1).map(function2).result()

compose(result, map(compose(function2, function1))(Something(input))

这样的结构存在吗?它有名字吗?即使这不存在并且我可以自己编写它,我也不知道该怎么称呼它。欢迎提出建议。

感谢您的帮助!

更新

按照@Bergi 的解决方案,我使用了Maybe.orElse。我写了一个名为 ShortCircuit 的小助手,我将其发布在下面,以防有人发现它有用。

import Maybe from "data.maybe";

const ShortCircuit = function(input, result) {
  this.input = input;
  this.result = result;
};

ShortCircuit.of = function(input, f) {
  return new ShortCircuit(input, Maybe.fromNullable(f(input)));
};

ShortCircuit.prototype.orElseMaybe = function(f) {
  return new ShortCircuit(this.input, this.result.orElse(() => Maybe.fromNullable(f(this.input))));
};

ShortCircuit.prototype.get = function() {
  return this.result.get();
};

export default ShortCircuit;

这是你如何使用它的:

const result = ShortCircuit.of(input, f1).orElseMaybe(f2).orElseMaybe(f3).get();

欢迎提出改进建议。

【问题讨论】:

  • 可以实现一个队列;或使用Promise
  • some 可能会有所帮助,而不是使用 map

标签: javascript functional-programming monads terminology functor


【解决方案1】:

您要查找的内容在 Haskell 中称为 Alternative type class。我还没有找到1一个实现它的JS库,虽然有support for it in PureScriptdiscussion about specifying it in FantasyLand

无论如何,我在 Folktale 中找到了一个完全符合您要求的函数:Maybe's orElse。你可以这样使用它:

Something(input).orElse(function1).orElse(function2).get() // `get` throws when all failed

更好的是,orElse 不仅适用于 Maybe,还适用于 EitherValidationTask

getOrElse method,称为orElse in Monet.js,并没有真正的帮助,因为它不会仅在失败的情况下执行您的“处理程序”。您可以使用cata 方法实现自己的Alternative

1:谷歌搜索“JS 替代方案”也不是很有帮助,即使您知道名称 :-)


哦,如果您使用 Promise,总有 .catch(…) method 具有广泛(ES6 支持)支持。

【讨论】:

  • 很好,orElse 看起来可以满足要求。让我尝试一下,我会回来确认。谢谢@Bergi!赞赏!
  • var toMaybe = function(f) { return function() { return Maybe.fromNullable(f()); } }; var result = Maybe.fromNullable(f1(input)).orElse(toMaybe(function() { return f2(input); })).orElse(toMaybe(function() { return f3(input); })).get(); 做到了。使用 ES6 箭头语法看起来更好。谢谢@Bergi
  • Maybe 实例和orElse@Bergi alt(Haskell 中的fantasy-land 或<|>)和orElse 具有相同的类型签名,但在Haskell 中的实现略有不同。我会说它们是相同的,但显然它们不是。它们有何不同?
  • @ftor 我不确定你在 Haskell 哪里找到了orElse?如果你从syb 包中引用this one,那确实和default instance Alternative Maybe 一样,只是写法不同。
  • @Bergi 是的,就是这样。我只是想知道他们为什么不重复使用它。肯定有原因,但可能并不重要。
猜你喜欢
  • 2014-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 2015-05-21
相关资源
最近更新 更多