javascript - 了解仿函数法则 0​​x104567911

标签 javascript functor commutativity

以下代码是用javascript编写的。

这个问题涉及尝试深入研究一些范畴论,也许 haskeller 或更熟悉这个问题的数学方面的人可以帮助我?

我正在努力思考仿函数是保留结构的类别之间的映射这一想法。更具体地说——根据我的理解——编程语言中的仿函数是一个内仿函数。这意味着编程语言中的仿函数是将类型和函数映射到编程语言中通常定义的更广泛的类型和函数类别中的子类别的态射。

据我所知,仿函数(或内仿函数)还必须遵守某些法则,这些法则通过促进组合和同一性来保护结构。

我发现几乎不可能创建一个我认为保留结构并遵守仿函数定律的仿函数。由于我只真正认真地使用 javascript 编程过,所以类型理论是我从未真正考虑过的事情(毕竟 JS 是无类型的),这使情况更加复杂。

我做了这个简单的例子,它把整数提升到一个最小的上下文中,在这个上下文中映射不适用于偶数。换句话说,你可以用你的构图映射,但一旦你击中偶数,节目就结束了。

这看起来有点像 Maybe:

class noEvens {
  constructor(x) {
    this._val = x;
  }
  static of(x) {
    return new noEvens(x);
  }
  isEven() {
    return this._val % 2 === 0;
  }
  map(projF) {
    return this.isEven() ? noEvens.of(null) : noEvens.of(projF(this._val));
  }
}

但很明显,在某些情况下,这不会与应用于普通 JS 类别中的整数的组合交换。考虑一个简单地将整数加一的投影函数。

如果我将一个偶数提升到这个 noEvens 上下文中,然后添加一个,它将给我一个 null 的 noEvens。但是,如果我先将一个加到一个偶数上,然后提升结果,它会导致奇数的 noEvens。

根据我的理解,这两种途径都应该根据仿函数定律进行交换。他们显然不会,因为通过每个上下文的相同映射在被提升后不会导致相同的结果“noEvens.of(value)”。

所以我想我的问题是,这是否意味着这不是仿函数?这种情况(按类型或其他)是什么让它表现得很奇怪?

我想我只是感到困惑,因为似乎所有“noEvens”所做的就是将值提升到一个新的上下文(子类别,无论什么)中,其中偶数不存在,但很明显某些路径不会上下类。

我发现将值“提升”到新的映射上下文中的想法非常直观,它为您提供了很多处理条件的机会,而无需实现大量冗余代码。但我不想假装我遵守某种形式化的“仿函数定律”系统。

我在分析这种情况时遗漏了什么类型系统和仿函数定律?

最佳答案

除了我的评论...

您可能会注意到您的近仿函数类也不满足恒等律。

const id = x => x;

new noEvens(2).map(id) // != new noEvens(2)

我的第一个想法是错误是允许首先构造一个包含偶数的 noEvens 对象。如果 isEven 检查改为在构造函数中完成,那么您可以满足 ID 法则。

class noEvens {
  constructor(x) {
    if (x % 2 === 0) {
      this._val = null;
    } else {
      this._val = x;
    }
  }
  static of(x) {
    return new noEvens(x);
  }
  map(projF) {
    if (this._val === null) {
      return noEvens.of(null);
    }

    return noEvens.of(projF(this._val));
  }
}

const id = x => x;

new noEvens(1).map(id)._val // ok: 1
new noEvens(2).map(id)._val // ok: null

但是,这个解还是不满足合成律。

const plusOne = x => x + 1;

// fmap f . fmap g == fmap (f . g) ?
new noEvens(1).map(plusOne).map(plusOne)._val // null
new noEvens(1).map(x => plusOne(plusOne(x)))._val // 3

所以最终我认为致命的缺陷是 noEvens 限制了它可以保存的数据类型。正如 Bergi 所说,“一个普通的仿函数能够包含任意数据。”所以 noEvens 作为一个概念的核心,不能是一个遵守合成法则的仿函数。

关于javascript - 了解仿函数法则 0​​x104567911,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48958881/

相关文章:

javascript - 使用 json 和功能搜索填充级联下拉列表

C++ 模板仿函数

python - 使所有符号在 sympy 表达式中可交换

c# - 带有 Nullable<T> 的 '==' 的参数顺序

javascript - 模块 MySQL Nodejs

javascript - 基于选择下拉列表的 Angular 2-Filtering 表(两者都是不同的组件)

c++ - 仿函数相关术语

c++ - Priority_queue 仿函数使用 C++

ruby - 3 等于或大小写相等运算符

javascript - 内部 CSS 不适用于 JS