haskell - 为什么 Haskell 中的 co 和逆变函子有区别,但范畴论没有区别?
问题描述
从范畴论的角度来看,这个答案包括以下陈述:
...事实是 co 和逆变函子之间没有真正的区别,因为每个函子都只是一个协变函子。
...
更详细地说,从 C 类到 D 类的逆变函子 F 只不过是 F 类型的(协变)函子:C op →D,从 C 的相反类别到 D 类。
另一方面,Haskell 的Functor
和Contravariant
仅要求fmap
和contramap
分别为实例定义。这表明,从 Haskell 的角度来看,存在对象是Contravariant
但不是Functor
s(反之亦然)。
Contravariant
因此,似乎在范畴论中“co 和逆变函子之间没有真正的区别”,而在 Haskell 中,和之间有区别Functor
。
我怀疑这种差异与 Haskell 中发生在 Hask 中的所有实现有关,但我不确定。
我想我自己理解类别理论和 Haskell 的每一个观点,但我正在努力寻找一种将两者联系起来的直觉。
解决方案
是为了方便。
可以使用更通用Functor
的类,并为 Hask 上的 endofunctors(对应于我们现有的Functor
)和从 Hask^op 到 Hask 的函子(对应于我们现有的 )定义实例Contravariant
。但这带来了象征性的认知成本和相当字面的句法成本:然后必须依靠类型推断或类型注释来选择实例,并且有显式转换(在标准库中命名Op
)getOp
进出 Hask^op .
使用名称fmap
并contramap
放宽这两种成本:读者不需要在头脑中运行 Hindley-Milner 来决定选择哪个实例,当它是明确的时,作者不需要给出明确的转换或类型注释来选择一个实例以防万一模棱两可的地方。
(实际上我在这里稍微改写了历史。真正的原因是因为语言设计者认为专业化Functor
会很有用,并且没有想象或没有看到需要更通用的Functor
. 人们后来发现它会有时是有用的。但是使用泛化Functor
类的经验表明这可能很乏味,而且由于上述原因,最常见的情况下的专门化类最终证明是非常合适的。)
推荐阅读
- python - pyppeteer - 如何通过使用 python pyppeteer 在页面中单击子链接 (href) 转到下一页
- android - 如何在物理设备上检测 Xamarin.forms android 中的网络调用?
- python - Django 框架 - 填充模型
- redis - 在 Redis 中查询频率统计信息?
- python - 删除一个词,除非它是另一个词的一部分
- docker - 使用 MinGW 编译的 Qt5 构建 Docker 映像在从“docker:latest”映像运行的容器中工作,但在 GitLab CI 中失败
- php - simplexml_load_string 不接受单个 XML 标记
- azure - PowerShell Azure 函数在执行时停止,没有错误消息
- grep - 仅使用“grep -v”完全匹配删除单词
- android - Android MY_PACKAGE_REPLACED 未在发布模式下调用