为什么会有这个问题 一个人可能会说zip
是一种Applicative
方法,通常的实例是ZipList
。我不喜欢它,因为它不安全。我也不喜欢Align
,因为它过于复杂,并且对于通常的情况来说不够具体。
合法类 在Haskell中,一些类型类可以被称为“合法”。这意味着它们带有必须满足的等式-该类的法律。这些法律通常来自于编程某个方面的范畴理论概念化。例如,Monad
是通过同名的范畴理论设备对计算 (无论其含义如何)进行概念化。
叠加事物 与事物盒子想要做的通常操作是将它们放在彼此上方,如果它们是幺半群,则它们将融合。
例如:
不够法律 通过幺半群函子和相应的Applicative
类型类来概念化这个概念。然而,令人讨厌的是,通常有两种定义Applicative
的方式都看起来合适。为什么呢?我认为答案是"法律不够"。
例如:
对于算术运算:
Sum
单子群是实际的“自身单子群”。它仅适用于相同类型的事物。例如,您不能将质量和力相加。Product
单子群将具有维度a
和b
的数字转换为具有维度c
的数字。相乘质量和力是合法的,并将我们带到温暖。
因此,正确的单子群选择可以从类型中推断出来。
对于列表:
对于矩阵:
- 通常的矩阵加法具有尺寸同质性的(非常合理的)要求,与上面提到的长度索引向量相同。由于矩阵通常用于各种现实世界的模拟,例如 3D 图形,一旦矩阵开始被裁剪或填充为零,人们会立即抱怨,因此类似于上面的
ZipList
的ZipMatrix
定义并不吸引人。 - 更奇怪的Kronecker 乘积类似于列表的直积。它还允许定义
Monad
。
- 通常的矩阵加法具有尺寸同质性的(非常合理的)要求,与上面提到的长度索引向量相同。由于矩阵通常用于各种现实世界的模拟,例如 3D 图形,一旦矩阵开始被裁剪或填充为零,人们会立即抱怨,因此类似于上面的
两种情况 从这些示例中可以看出,在我们称之为“单子群”或“单子范畴函子”的事物中混杂着两个不同的想法,这种区别对于编程非常重要(与纯理论不同),因为它可以清除混乱,消除不安全因素,并且主要是因为在每种情况下都有两个完全不相关的算法需要运行。
我认为单源函子的可逆性(也称为“强度”)可能很重要。但是对于Peano自然数的Sum和Product单源操作的结果是无法区分的。(我不确定它们是否可以被认为是单源自函子。)所以,我猜测类型的变化是关键。甚至物理数量的乘法也不能作为Monoid进行类型检查!
附注:存在一种基于笛卡尔积的长度索引向量和基于Kronecker乘法的矩阵的Monad实例,其中使用某种形式的fold zip作为join。
liftA2(,)xs ys==liftA2(,)xs'ys'
,那么xs==xs'
和ys==ys'
”。但是通常用于列表的Applicative
实例(我认为您称之为“直和”)被认为是可逆的,但不符合此定义(例如liftA2(,)[] [()] == liftA2(,)[()] []
),因此我不清楚您在这里想要什么。(这不是关于空值的争论:还有一些非空列表会破坏可逆性。) - Daniel Wagner(a -> b -> c) -> v n a -> v m b -> v (n * m) c
)和zip类型((a -> b -> c) -> v n a -> v n b -> v n c
)之外,还有一种用于矩阵的收缩类型:Monoid c => (
a -> b -> c) -> m x y a -> m y z b -> m x z c`。话虽如此,我认为这个操作最适合放在一个形状索引应用程序中。这适用于向量,因为它们显然是可压缩的,并且大小很容易表达。它也适用于函数,但不适用于映射。 - Dan RobertsonMonoid
实际上没有太多关系:前者指的是单一的_类型级别的monoid_(()
,(,)
),后者指的是Haskell类型中各种值级别的monoid。 - leftaroundaboutx :: A
和y :: B
放在元组(x,y)
中,因为稍后将可用函数f :: A-> B-> C
将它们融合在一起。 因此,人们可以将它们包装在data W = WA A | WB B | WC C
中,并定义一个instance Monoid W where mappend (WA x) (WB y) = WC $ f x y
。 这能更好地证明我的论点吗? - Ignat Insarov