了解函子定律:这是函子吗? [英] Understanding functor laws: is this a functor?

查看:71
本文介绍了了解函子定律:这是函子吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是用javascript编写的.

The following code is written in javascript.

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

This question involves an attempt to dive into some category theory, maybe a haskeller or someone more familiar with the mathematical aspects of this question can help me out?

我正在尝试围绕函子是类别之间保留结构的映射这一观点展开思考.更具体地说-根据我的理解-编程语言中的函子是endofunctor.这意味着编程语言中的函子是态素,其将类型和功能映射到编程语言中通常定义的更广泛的类型和功能类别中的子类别.

I'm trying to wrap my head around the idea that a functor is a mapping between categories that preserves structure. More specifically - according to my understanding - a functor in a programming language is an endofunctor. By this it is meant that functors in programming languages are morphisms that map types and functions to a sub-category within the broader category of types and functions as defined generally within the programming language.

据我所知,函子(或内函子)还必须遵守某些法律,这些法律可以通过促进成分和身份来保护结构.

According to my knowledge, functors (or endofunctors) must also adhere to certain laws that afford preservation of structure via the facilitation of composition and identity.

我发现几乎不可能创建我认为能保留结构并遵守函子定律的函子.我还只是认真地使用javascript进行了编程,这使事实更加复杂,所以类型理论是我从未真正考虑过的事情(毕竟JS是无类型的).

I'm finding it almost impossible to create a functor that I feel preserves structure, and adheres to the functor laws. This is compounded by the fact that I've only really programmed seriously in javascript, so type theory is something I've never really thought about (JS is untyped after all).

我做了一个简单的示例,将整数提升到一个最小上下文,在该上下文中,映射对偶数不起作用.换句话说,您可以根据自己的构图进行映射,但是一旦您击中一个偶数,该节目即告结束.

I made this simple example that lifts integers into a minimal context where mappings won't work on even numbers. In other words, you can map away with your composition but as soon as you hit an even number the show is over.

这看起来像是Maybe:

This looks sort of like a 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类别中的整数的组合并不矛盾.考虑一个简单地将一个加到一个整数的投影函数.

But it's evident that this won't commute with compositions applied to integers in the normal JS category under certain situations. Consider a projection function that simply adds one to an integer.

如果在这个noEvens上下文中增加一个偶数,然后再加一个,它将给我一个noEvens为null.但是,如果我先将偶数加一个,然后求和,则结果将是一个奇数的noEvens.

If I lift an even number into this noEvens context and then add one it will give me a noEvens of null. But, if I first add one to an even number, then lift the result, it will result in a noEvens of an odd Number.

根据我的理解,这两种途径都应该在函子定律的基础上进行交流.它们显然不是因为在每个上下文中的相同映射在被提升后不会导致相同的结果"noEvens.of(value)".

According to my understanding, both of these pathways should commute under functor laws. They clearly don't because the same mappings through each context don't result in the same resultant "noEvens.of(value)" after being lifted.

所以我想我的问题是,这是否意味着它不是函子?这种类型的情况(无论是类型还是其他)导致异常行为是什么?

So I guess my question is, does this mean that this is not a functor? What is it about this type of situation (type-wise or whatever) that makes it act strangely?

我想我只是感到困惑,因为似乎所有"noEvens"所做的就是将值提升到一个甚至没有数字的新环境(子类别,无论如何)中,但是很明显,某些途径不会上下班.

I guess I'm just confused because it seems to be that all "noEvens" does is lift values into a new context (sub-category, whatever) where even numbers don't exist, but it is obvious that certain pathways won't commute.

我发现将价值提升"到新的映射上下文中的想法非常直观,它为您提供了很多处理条件的机会,而无需实现大量的冗余代码.但是我不想以虚假的名义这样做,因为我坚持使用某种形式的"functor law"制度.

I find the idea of "lifting a value" into a new mapping context quite intuitive, and it affords you a lot of opportunities to deal with conditions without having to implement tonnes of redundant code. But I don't want to do so in the false pretense that I'm adhering to some formalized system of "functor laws".

在这种情况的分析中我缺少的类型系统和函子定律是什么?

What is it about type-systems and functor laws that I'm missing in my analysis of this situation?

推荐答案

除了我的评论...

您可能会注意到,几乎是班级不一的班也不符合身份法.

You may notice that your almost-functor class also doesn't satisfy the identity law.

const id = x => x;

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

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

My first thought was that the mistake was allowing a noEvens object containing an even number to be constructed in the first place. If the isEven check was instead done in the constructor, then you could satisfy the ID law.

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

但是,事实证明该解决方案仍不满足组成定律.

But, it turns out this solution still doesn't satisfy the composition law.

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作为一个概念,其核心不能是遵循合成定律的函子.

So ultimately I think the fatal flaw is that noEvens limits what kind of data it can hold. As Bergi also said, "A usual functor would be capable of containing any arbitrary data." So noEvens, at its core, as a concept, cannot be a functor that obeys the composition law.

这篇关于了解函子定律:这是函子吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆