可能是javascript解释中的monad示例代码



我正在开始或尝试学习函数式编程monad。

所以第一个是"也许"。我正在尝试用monad转换代码。

function(fieldName, vals, fields) {
var newValue = vals[fieldName];
if (typeof(newValue) == 'undefined') {
var elemFrom = fields[fieldName];
if (elemFrom) {
newValue = fields[fieldName]
}
}
if (typeof (newValue) != 'undefined') {
return newValue
}
}

这里我有一堆未定义的检查,我认为这是monay的好用。

我的问题是,我读到您将值传递给可能的monad和map函数。

然而,在我的情况下,我会替换monad中的值。

如果我传递null,map方法将不会执行任何操作,因为该值未定义。

我没有使用框架,我想要简单的实现,这样我就能理解它

我应该在maybe monad类(函数(中添加"else"方法吗。

我有相反的情况"如果值未定义,就做点什么">

你能建议如何解决问题吗

谢谢

因此您发布的函数可以重写为

const f = (a, b, c) => b[a] === undefined ? c[a] : b[a];

我不清楚这是否需要成为一个函数,而不是在任何你想使用相关对象属性的地方内联,但我不判断你可能部分应用了它或其他什么。

至于Maybe,一个(非常简单的(实现可能看起来像这样:

class Maybe {
static of (value) {
return new Maybe(value);
}
// Proper solution here should be recursive to handle
// nesting properly, but I'm lazy
static equals (a, b) {
return a.chain(x => x) === b.chain(x => x);
}
constructor(value) {
this._value = value;
}
map (f) {
// Does not distinguish null from undefined, but YMMV. Note
// that if the Maybe value is null or undefined we never touch
// f, that's the null propagation thing.
return this._value == null ? this : new Maybe(f(this._value));
}
chain (f) {
const result = this._value == null ? this : f(this._value);
console.assert(result instanceof Maybe);
return result;
}
}

现在我们可以测试它是否符合莫纳德定律:

const a = 3;
const f = x => Maybe.of(x * x);
Maybe.of(a).chain(f) === f(a) // left identity
Maybe.equals(Maybe.of(5).chain(Maybe.of), Maybe.of(5)); // right identity

这是一个有效的Functor

Maybe.equals(Maybe.of(3).map(x => x), Maybe.of(3)); // identity
Maybe.equals(                                       // composition
Maybe.of(3).map(x => x + 2).map(x => x * 3), 
Maybe.of(3).map(compose(x => x * 3, x => x + 2))
);

太好了。

所以现在,到你的功能。它将被重写为

const f = (a, b, c) => {
return b[a] === undefined ? Maybe.of(c[a]) : Maybe.of(b[a]);
}

也许你现在明白了我困惑的原因,也许在这里并没有真正救你多少。但如果我用的是,也许我会把整个东西重写成这样:

const or = (a, b) => {
return Maybe.of(a == null ? b : a);
}

然后我只需要传入属性访问:

const obj1 = { a: 2, c: 3 };
const obj2 = { b: 4 };
const prop = "a"
const result = or(obj1["prop"], obj2["prop"]); // Maybe(2)

更新

感谢@Bergi在评论中提醒我Alternative。你可以在上面的Maybe类中添加一个方法,如下所示:

alt (x) {
if (!(x instanceof Maybe)) {
throw new TypeError("Expected a Maybe");
}
return this.chain(x => x) == null ? x : this;
}
// semantics
Maybe.of(null).alt(Maybe.of(3)); // Maybe(3)
Maybe.of(2).alt(Maybe.of(4));    // Maybe(2)
// usage
Maybe.of(obj1[prop]).alt(Maybe.of(obj2[prop]));

注意,这并不能完全满足Alternative的实现(您还需要一个zero/empty方法(,但您可以阅读此处和此处了解更多详细信息。这可能是您发布的功能的最佳替代品。

最新更新