我正在开始或尝试学习函数式编程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方法(,但您可以阅读此处和此处了解更多详细信息。这可能是您发布的功能的最佳替代品。