haskell - 由于柯里化(Currying),arity-n 的函数真的只是一个 n 类吗?可以做成 1 类吗?

标签 haskell currying category-theory arity

这个问题有一个很长的前奏,然后我才能真正问出来:)
假设类型 A 和 B 代表类别,那么函数

f :: B -> A


是两个范畴之间的态射。我们可以创建一个新类别,其中 A 和 B 作为对象,f 作为箭头,如下所示:
enter image description here
现在,让我们引入一个新的类别 C 和函数 g:

g :: C -> B -> A


我希望能够将 C 和 g 添加到我上面的类别中,但我不确定该怎么做。直观地说,我想要这样的东西:
enter image description here
但我以前从未在类别图中看到过类似的东西。为了使这个洁净,我可以引入一个虚拟箭头 g' 并构造一个像这样的 2 类:
enter image description here
但这似乎是一个迟钝的画面。 (当然,我们可以使用我上面画的图片作为正确图片的简写。)而且,现在也不完全清楚 g 和 g' 到底是什么。 g 不再是一个将类别 C 作为输入并返回态射::B -> A 的函数。相反,

g' :: (C -> C)

g :: (C -> C) -> (B -> A)


如果我们通过 g 身份,那么一切都会正常工作。但是如果我们给它传递一些其他函数,那么谁知道会发生什么?
所以我的问题是:n 类别中的 n 箭头真的是我们应该考虑具有 arity n 的函数的方式吗?还是有一些更简单的方法可以将此功能表示为我错过的标准类别?

最佳答案

在这里谈论“类别之间的态射”听起来像是一个可能的类别错误(哈,哈)。在 Haskell 中,我们最常谈论一个所谓的类别 哈斯克 ,这是其对象是类型 * 的类别的一些不一致的理想化 (0) 版本态射是函数。如果它们不是 的态射,则不清楚类别之间的“功能”是什么。哈斯克 .

另一方面,在更一般的设置中,您当然可以定义一个类别,其对象是其他类别(1),具有您想要的任何态射,以满足必要的属性。通常的例子是 , 类别 small categories其态射是仿函数。

也就是说,无论哪种情况,您的问题的答案都基本相同。要谈论两个对象之间的态射集合,就好像该集合本身就是一个对象——即,作为其他态射的源或目的地——你需要一个对象来扮演这个角色,并且需要某种方式来间接地谈论态射,以便你可以来回翻译。

如果我们已经有一种方法可以将对象对作为单个对象(通常称为某种“乘积”)进行讨论,那么一种方法是定义态射集合 A⊗B→C 和态射 A→CB 的集合,它允许对象 CB 代表态射 B→C 的集合。

如果有问题的“对象对”实际上是 categorical product , 我们有 a cartesian closed category , 这两个 哈斯克是。在 Haskell 中,上述等价函数是 curryuncurry (2)。

当然,这不是谈论态射作为对象的唯一方式。一般概念简称为“封闭范畴”。但是,如果您正在考虑高阶函数和函数式编程,那么您可能会想到一个笛卡尔封闭类别。

(0) 这通常涉及诸如假装 ⊥ 不存在(因此所有函数都是全部的)以及将产生相同输出的函数视为相同的事情(例如,忽略性能差异)。

(1) 但是不要试图谈论对象都是类别的类别,否则Bertrand Russell's会给你生意的。

(2) 当然,以 the logician Haskell Curry 命名.

关于haskell - 由于柯里化(Currying),arity-n 的函数真的只是一个 n 类吗?可以做成 1 类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12571161/

相关文章:

haskell - 在 Haskell 中是否有更好的方法来使用可选函数参数?

haskell - 递归未终止

ruby - 用 Ruby 折叠和柯里化(Currying)

functional-programming - 使用 Ramda : Can you curry a function that takes unlimited number of arguments 进行函数式编程

haskell - 为什么从根本上说遍历是在 Applicatives 上定义的?

haskell - 是否可以在没有 prof 库的情况下分析 Haskell 程序?

haskell - Haskell 中的诊断输出

javascript - 回调,错误 : is not a function

haskell - 编译器如何确定仿函数的固定点以及 cata 如何在叶级工作?

haskell - (\f -> fmap f id) 是否总是等价于 arr?