Agda和Idris之间的区别

190

我开始深入研究依赖类型编程,并发现Agda和Idris语言最接近Haskell,所以我从那里开始。

我的问题是:它们之间的主要区别是什么?它们的类型系统是否同样具有表现力?很好地进行全面比较并讨论其优点。

我已经能够发现一些差异:

  • Idris具有类似于Haskell的类型类,而Agda则采用实例参数
  • Idris包括单子和应用符号
  • 两者似乎都具有某种可重新绑定的语法,尽管不确定是否相同。

编辑: 在这个问题的Reddit页面上还有更多答案:http://www.reddit.com/r/dependent_types/comments/q8n2q/agda_vs_idris/


1
你可能也想看看Coq,它的语法与Haskell相似,而且它有易于使用的类型类 :) - user181351
4
记录一下:现在Agda也有单子和函子应用符号表示法。 - gallais
2个回答

210
我可能不是最好的回答者,因为我已经实现了Idris,所以可能有些偏见!FAQ - http://docs.idris-lang.org/en/latest/faq/faq.html - 对此有一些解释,但是稍微扩展一下:

Idris从一开始就被设计成支持通用编程而不是定理证明,因此具有高级特性,如类型类、do表示法、范畴括号、列表推导、重载等。Idris把高级编程放在交互式证明之前,尽管因为Idris建立在基于策略的展开器上,所以有一个与策略相关的交互式定理证明接口(有点像Coq,但不那么先进,至少目前还不是)。

另一个 Idris 旨在很好支持的是嵌入式 DSL 实现。使用 Haskell,您可以通过 do 符号实现很多功能,使用 Idris 也可以,但如果需要,您还可以重新绑定其他结构,例如应用和变量绑定。您可以在教程中找到更多详细信息,或在此论文中找到完整详细信息:http://eb.host.cs.st-andrews.ac.uk/drafts/dsl-idris.pdf 另一个区别在于编译。Agda 主要通过 Haskell 进行,Idris 通过 C 进行。有一个实验性的 Agda 后端使用与 Idris 相同的后端,通过 C 进行。我不知道它是否得到了良好的维护。 Idris 的主要目标始终是生成高效的代码 - 我们可以做得比目前更好,但我们正在努力。

Agda和Idris中的类型系统在许多重要方面非常相似。我认为主要区别在于宇宙的处理。Agda具有宇宙多态性,Idris具有cumulativity(如果您发现这太限制并且不介意证明可能不正确,则两者都可以使用Set:Set)。


59
你的意思是,“不是最好回答这个问题的人”是什么?由于你非常了解Idris,所以你是最好回答这个问题的人之一。现在我们只需要等待NAD的回复,就能得到完整的信息了 :) 感谢你抽出时间来回复。 - Alex R
9
有没有地方可以阅读更多关于累加性的内容?我以前从未听说过这个词…… - serras
13
Adam Chlipala的书《Certified Programming with Dependent Types》(http://adam.chlipala.net/cpdt/html/Universes.html)可能是最好的选择。 - Edwin Brady
8
如果简洁明了地表述,HoTT书籍的第一章也能很清晰地描述它。 - David Christiansen
1
这个DSL只在Idris 1中吗?如果是,是否值得提一下? - joel

56

Idris和Agda之间的另一个区别是,Idris的命题等式是异构的,而Agda的是同构的。

换句话说,在Idris中所谓的等式定义为:

data (=) : {a, b : Type} -> a -> b -> Type where
  refl : x = x

当在Agda中时,它是

data _≡_ {l} {A : Set l} (x : A) : ASet a where
    refl : x ≡ x

在Agda定义中,l可以被忽略,因为它与Edwin在他的答案中提到的宇宙多态有关。

重要的区别是,在Agda中,相等类型将A的两个元素作为参数,而在Idris中,它可以将两个具有潜在不同类型的值作为参数。

换句话说,在Idris中,人们可以声称具有不同类型的两个东西是相等的(即使最终这是一个无法证明的声明),而在Agda中,这种说法本身就是无意义的。

对于类型理论,这对于同伦类型理论的可行性尤其具有重要和广泛的影响。对于这一点,异构相等性根本行不通,因为它需要与HoTT不一致的公理。另一方面,使用异构相等性可以陈述一些有用的定理,这些定理不能直接使用同构相等性来陈述。

也许最简单的例子是向量连接的结合律。给定称为向量的长度索引列表的定义如下:

data Vect : Nat -> Type -> Type where
  Nil : Vect 0 a
  (::) : a -> Vect n a -> Vect (S n) a 

并且与以下类型连接:

(++) : Vect n a -> Vect m a -> Vect (n + m) a

我们可能希望证明:

concatAssoc : (xs : Vect n a) -> (ys : Vect m a) -> (zs : Vect o a) ->
              xs ++ (ys ++ zs) = (xs ++ ys) ++ zs

在同性等式下,这个语句毫无意义,因为等式左侧的类型是 Vect (n + (m + o)) a ,而右侧的类型是 Vect ((n + m) + o) a 。但在异性等式下,这个语句是完全有意义的。


29
您似乎更多地评论Agda标准库而不是Agda潜在的理论,但即使标准库包含同态和异态等式(http://www.cse.chalmers.se/~nad/listings/lib/Relation.Binary.HeterogeneousEquality.html#1),人们也倾向于在可能的情况下使用前者。后者相当于一个类型相等的声明加上一个关于值的声明。在一个类型相等很奇怪的世界(HoTT)中,heteq则是一个更奇怪的声明。 - Mysterious Dan
7
我不理解在同质等式下那个陈述为什么是无意义的。除非我错了,(n + (m + o))((n + m) + o)根据自然数上 + 的结合律(从归纳原理得出)在判断上是相等的。因此,等式两边的类型是相同的。虽然等式类型的差异很重要,但我看不出这是一个例子。 - user788472
5
@Abhishek,判断平等和定义平等不是相同的吗?我认为你的意思是(n + (m + o)) 和 ((n + m) + o) 在命题上是相等的,但在定义/判断上不是相等的。 - Tom Crockett
3
当我说"判断相等"时,我的意思是"命题相等"。对不起。这是更正后的评论: (n + (m + o)) 和 ((n + m) + o) 在命题上是相等的,但在定义上不相等。如果你有一个 a:A,那么只有当 A 和 B 在定义上相等时,a:B 才成立。为了使类型检查可决定,定义相等必须是可判定的。在外延类型理论中,定义相等与命题相等重合,因此类型检查是不可判定的。在 Coq 中,定义相等仅包括计算、α 等价和定义展开。 - Abhishek Anand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接