javascript - 有没有办法给 curry 箭头函数一个类型/标签?

标签 javascript types functional-programming church-encoding

函数编码类型(即嵌套柯里化(Currying)函数)在 Javascript 中有一些缺点:

  • 他们在开发控制台中的表示是混淆的(例如 [Some(5), None] 显示为 [f, f])
  • 没有什么可以阻止您将组合子应用于错误的类型(例如 eitherMap(f) (Some(5)))
  • 你不能检查他们的自由变量
  • 你甚至不能躲避它们

这些缺点使它们在实际应用中毫无用处。

我想知道是否有办法克服这些缺点并提出以下草图:

const tag = (name, x, k) => {
  const Cons =
    Function(`return function ${name}() {}`) ();

  Cons.prototype[Symbol.toStringTag] = name;
  Cons.prototype["run" + name] = k;
  Cons.prototype.tag = name;

  const o = new Cons();
  Object.defineProperty(o, "value", {get: () => x});
  return o;
};

const Some = x =>
  tag("Option", x, def =>
    tag("Option", x, k => k(x)));

const None = tag("Option", null, def =>
  tag("Option", def, k => def));

const option = def => k => fx =>
  fx.runOption(def).runOption(k);

const safeInc = option(0) (n => n + 1);

safeInc(Some(5)); // 6
safeInc(None); // 0

const xs = [Some("foo"), None]; // [Option, Option]

/* 
  expanded dev console display:

  1: Option {value: ...} --> expands to "foo"
  2: Otpion {value: ...} --> expands to null
*/

请注意,我对原型(prototype)继承一​​点都不感兴趣。

这种方法既乏味又可能很慢,因为我应用了 Function 构造函数,这使得代码更难预测。有没有更好的方法给柯里化(Currying)函数一个类型(或者更确切地说是 JS 中的一个标签),从而消除列出的缺点?

最佳答案

我稍微改进了我的方法并摆脱了 Function 调用和构造函数的重复创建。它适用于我的特定用例(函数编码类型),但我未能解决柯里化(Currying)形式的任意函数的更一般情况,因为它仍然太乏味。无论如何,它在这里:

const tag = Cons => (k, ...args) => {
  const o = new Cons();

  Object.defineProperties(o, {
    "value": {get: () => args},
    "runOpt": {value: k}});

  return o;
};


const Opt = tag(
  function Option() {
    Option.prototype[Symbol.toStringTag] = "Option";
    Option.prototype.tag = "Option";
  });


const Some = x =>
  Opt(def => Opt(k => k(x), x), x);

const None = Opt(def => Opt(k => def, def));

const option = def => k => fx =>
  fx.runOpt(def).runOpt(k);

const safeInc = option(0) (n => n + 1);

safeInc(Some(5)); // 6
safeInc(None); // 0

Some(5); // Option {runOption}
[Some("foo"), None]; // [Option, Option]

/*
  expanded dev console display:

  1: Option {runOpt: f, value: ...} --> expands to ["foo"]
  2: Otpion {runOpt: f, value: ...} --> expands to []
*/

关于javascript - 有没有办法给 curry 箭头函数一个类型/标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53468084/

相关文章:

javascript - 我怎样才能使可折叠的内容默认传播(显示)

c++ - 具有模板化参数的模板函数的类型推断

c++ - 如何重构容器以直接使用谓词方法?

arrays - Swift:将一组字典扁平化为一个字典

javascript - 脚本438 : Object doesn't support property or method 'indexOf'

javascript - 在页面刷新之前,React 路由不起作用

Java 启动错误选择不包含主类型

sql - 如何确定 mysql 数据库的类型 : whether it is InnoDB or MyISAM?

functional-programming - 您将如何在 Clojure 或一般的函数式语言中实现按契约(Contract)设计?

javascript - VIVE 耳机上的 THREE.js(Steam 中的 JS/浏览器/WebGL)