为什么过滤器基于依赖对?

时间:2017-08-14 14:29:57

标签: idris

Idris Tutorial中,过滤向量的函数基于从属对。

filter : (a -> Bool) -> Vect n a -> (p ** Vect p a)
filter f [] = (_ ** [])
filter f (x :: xs) with (filter f xs )
  | (_ ** xs') = if (f x) then (_ ** x :: xs') else (_ ** xs')

但为什么有必要用依赖对来代替更直接的东西呢?

filter' : (a -> Bool) -> Vect n a -> Vect p a

在这两种情况下,必须确定p的类型,但在我认为的替代方案中,列出p两次的冗余将被消除。

我实施filter'的天真尝试失败了,所以我想知道是否有一个根本原因无法实施?或者filter'可以实施,也许filter只是在伊德里斯展示依赖对的一个不好的例子吗?但如果是这种情况那么在什么情况下依赖对会有用呢?

谢谢!

2 个答案:

答案 0 :(得分:7)

filterfilter'之间的区别在于存在主义和普遍量化。如果(a -> Bool) -> Vect n a -> Vect p afilter的正确类型,则表示filter返回长度为p的Vector,调用者可以指定p应该是什么。

答案 1 :(得分:5)

金·斯特贝尔answer对这笔钱是正确的。我要注意的是,这已经在2012年的伊德里斯邮件列表中进行了讨论(!!):

那里发布的raichoo可以帮助澄清我的想法;您filter'真实签名是

filter' : {p : Nat} -> {n: Nat} -> {a: Type} -> (a -> Bool) -> Vect a n -> Vect a p

从中可以明显看出,过滤器应该(甚至可以)做什么; p实际上依赖对你正在过滤的谓词和向量,你可以(实际上需要)使用依赖对来表达它。请注意,在(p ** Vect p a)对中,p(以及Vect p a)隐含地取决于在其签名中出现在它之前的(未命名的)谓词和向量。

扩展这个,为什么是一个依赖对?你想要返回一个向量,但是没有" Vector长度未知"类型;您需要一个的长度来获取Vector类型。但是你可以想一想,好吧,我会将一个Nat和一个长度为#34;的向量一起返回。不出所料,这对的类型是一个从属对的例子。更详细地,从属对DPair a P是由

构建的类型
  1. 类型a
  2. 功能P: a -> Type
  3. 该类型DPair a P的值是的值

    1. x: a
    2. y: P a
    3. 此时我认为这只是可能误导你的语法。类型p ** Vect p a DPair Nat (\p => Vect p a); p没有过滤器的参数或类似的东西。所有这些起初可能有点令人困惑;如果是这样,也许它有助于将p ** Vect p a视为长度未知的" Vector的替代品"类型。