用于链接和终止操作序列的函子或单子的名称和存在性

问题描述 投票:0回答:1

我正在查看诸如 Folktalemonet.js 之类的库,我喜欢能够使用

map
链接操作而无需空检查或
if
语句,例如使用
Maybe
Either
Task

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

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

换句话说,我正在寻找类似于

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

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

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();

欢迎提出改进建议。

javascript functional-programming monads terminology functor
1个回答
7
投票

您正在寻找的内容在 Haskell 中被称为

Alternative
类型类。我还没有找到1实现它的 JS 库,尽管在 PureScript 中有对它的支持以及关于在 FantasyLand 中指定它的讨论

无论如何,我在 Folktale 中找到了一个函数,它完全可以满足您的需求:Maybe 的

orElse
。你会像这样使用它:

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

更好的是,

orElse
不仅适用于
Maybe
,还适用于
Either
Validation
Task

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

1:谷歌搜索“JS替代品”也没有多大帮助,即使你知道名字:-)


哦,万一您使用的是 Promise,总有

.catch(…)
方法,它具有广泛的(ES6 支持)支持。

© www.soinside.com 2019 - 2024. All rights reserved.