也许在JavaScript说明中有monad示例代码

时间:2018-12-10 06:28:50

标签: javascript functional-programming

我正在开始或试图学习函数式编程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方法将不会显示。

我没有使用框架,我想要简单的实现,以便我能理解它。

是否应该在monad类(函数)中添加“ else”方法。

我遇到了相反的情况“如果值未定义,请执行一些操作”

您能建议解决问题的方法吗

谢谢

1 个答案:

答案 0 :(得分:1)

因此您发布的功能可以重写为

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;
  }
}

现在我们可以测试它是否符合Monad法律:

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

那是有效的仿函数

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]);
}

也许您现在看到我感到困惑的原因,也许在这里并没有为您节省很多。但是,如果我使用的是Maybe,我会像这样重写整个内容:

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。您可以像上面这样向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的实现(您还需要一个零/空方法),但是您可以阅读herehere以获得更多详细信息。这可能是您发布的功能的最佳替代品。