Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可能是javascript解释中的monad示例代码_Javascript_Functional Programming - Fatal编程技术网

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

可能是javascript解释中的monad示例代码,javascript,functional-programming,Javascript,Functional Programming,我正在开始或尝试学习函数式编程单子 所以第一个可能是。我想用monad转换代码 function(fieldName, vals, fields) { var newValue = vals[fieldName]; if (typeof(newValue) == 'undefined') { var elemFrom = fields[fieldName]; if (elemFrom) { newValue = fields

我正在开始或尝试学习函数式编程单子

所以第一个可能是。我想用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的一个很好的用途

我的问题是,我读到您将值传递给maybe 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 or = (a, b) => {
  return Maybe.of(a == null ? b : a);
}
现在我们可以测试它是否符合单子定律:

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]);
}
也许你现在明白我困惑的原因了,也许这并没有给你带来多少好处。但是如果我用的话,也许我会把整个事情改写成这样:

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

注意,这并不能完全满足作为替代方法的实现(您还需要一个零/空方法),但您可以阅读和了解更多详细信息。这可能是您发布的函数的最佳替代品。

您发布的代码没有任何一元性。你真正的问题是什么?另外,如果你想学习FP,单子是一个糟糕的起点。问题的关键是我如何用Maybe monad翻译代码,因为我不能“我读到你把值传递给Maybe monad和map函数”-嗯,要使用单子,你要使用
chain
函数(或
bind
flatMap
或其他任何名称)我添加了JavaScript标记。以后请务必添加该标记,语法突出显示依赖于它:)您可能希望在
Maybe
数据类型上实现一个
备选
实例-这就是这里实际需要的。@Bergi谢谢,在Control.Applicative中添加了一个快速而肮脏的方法,其中包含到幻想世界和可选类的链接。如果我遗漏了任何其他内容,请告诉我。我认为应该是
可能。from(null)。alt(可能。from(3))
@Bergi修复了它。回顾这一点,您的
chain
方法似乎完全不正确。它应该简单地读取
并返回此值。\u value==null?这个:f(这个值)
(其中
f(此._值)
可以断言为
实例,可能是
-而不是任何monad)。