为什么 一个人可能会说这zip是一个Applicative通常的例子ZipList.我对它不满意,因为它不安全.我也不满意Align,因为它是无所不包的,过于复杂,而且对于通常情况来说不够具体.
合法类 Haskell中的某些类型类可能被称为合法类.这意味着他们必须拥有必须持有的平等 - 一个阶级的法律.通常这些规律来自编程方面的范畴理论概念化.例如,Monad是通过同名类别理论设备对计算 进行概念化(无论是什么意思).
重叠事物 想要处理事物的通常操作是将它们放在彼此之上,如果它们是幺半群,它们将融合在一起.
例子:
没有足够的定律 这个概念的概念化是通过monoidal仿函数和相应的Applicative类型类.然而,存在令人烦恼的复杂性,因为通常有两种方式来定义Applicative两者看起来都合适.为什么这样?我建议答案是"法律不够".
例子:
对于算术:
Sum独异的是实际的"内切半群".它对于亲属来说是合法的.例如,你无法总结质量和力量.Product半群需要维数a和b多项维度c.将质量和力量相乘是合法的,让我们变得温暖.因此,monoid的正确选择可以从类型中推断出来.
对于列表:
对于矩阵:
ZipMatrix沿着上述线条的定义ZipList似乎没有吸引力.Monad.两个案例 从这些例子中可以看出,在我们称之为"monoid"或"monoidal functor"的事物中,有两个不同的想法混杂在一起,而这种区别对于编程非常重要(可能与纯理论不同),因为它会清除混乱,删除unsafeties,主要是因为在每种情况下都有两个完全不相关的算法运行.
我在想,幺半向函子的可逆性(也称为 "强度" )才是最重要的.但是对Peano天然产品的Sum和Product Monoidal运算的结果是难以区分的.(我不确定它们是否可以被认为是单一的内向导体.)所以,我转向猜测类型的变化是标志.物理量的乘法不会将检查作为a Monoid,甚至!
PS它本身就是一个Monad用于长度索引向量的实例,用于笛卡尔积和矩阵超过Kronecker乘法,某种类型fold zip为join.
精确荏苒(作为安全包调用它)能够通过表达的Representable类.有相当多的理论与之相关Representable.就我们目前的目的而言,我们可以专注于......
一个
Functorf是Representable,如果tabulate和index见证的同构到(->) x.
......和:
Haskell类型的可表示的endofunctors与读者monad同构,因此可以免费继承大量的属性.
由于Representable仿函数与某种类型的函数同构(例如,同构对是同构的Bool -> a,并且无限流是同构的Nat -> a),因此可以通过逐点压缩函数来实现精确的压缩.这就是's mzipRep的默认实现:MonadZipmzip
mzipRep :: Representable f => f a -> f b -> f (a, b)
mzipRep as bs = tabulate (index as &&& index bs)
Run Code Online (Sandbox Code Playgroud)
虽然MonadZip是一个相当尴尬的课程(它主要是MonadComprehensions扩展实施的一部分),但它有一个相关的法律,我将以非一元的术语重述它:
信息保存:如果
() <$ u = () <$ v那么munzip (mzip u v) = (u, v)
换句话说,如果u并且v具有相同的形状,则mzip不会丢弃信息(因此可以撤消信息munzip).由于Representable暗示只有一种可能的形状,它允许我们放弃条件,从而获得精确的压缩.
切线说明:
该
ZipList定义显然不安全.定义为,给定两个不同长度的列表,将较长的一个裁剪为较短的长度.
我会说这取决于你想用什么拉链.有时你会想要或需要精确的压缩,有时候你不会(例如,考虑将索引附加到列表的常见技巧zip [0..]); 有时候填充而不是修剪将是有意义的(参见leftaroundabout的评论).这就是为什么我更喜欢称为精确拉链"精确",而不是"安全".
然而,存在令人烦恼的复杂性,因为通常有两种方式来定义
Applicative两者看起来都合适.为什么这样?我建议答案是"法律不够".
我非常不同意如果某个类允许多个实例用于某些数据类型,则该类未被指定.我宁愿说,例如带有笛卡尔积的应用程序列表和带有压缩应用程序的列表是不同的结构,以相关的态射为特征 - 它恰好可以通过相同的数据类型在Haskell中表示.