在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
只是在伊德里斯展示依赖对的一个不好的例子吗?但如果是这种情况那么在什么情况下依赖对会有用呢?
谢谢!
答案 0 :(得分:7)
filter
和filter'
之间的区别在于存在主义和普遍量化。如果(a -> Bool) -> Vect n a -> Vect p a
是filter
的正确类型,则表示filter
返回长度为p的Vector,调用者可以指定p应该是什么。
答案 1 :(得分:5)
那里发布的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
是由
a
P: a -> Type
该类型DPair a P
的值是对的值
x: a
y: P a
此时我认为这只是可能误导你的语法。类型p ** Vect p a
是 DPair Nat (\p => Vect p a)
; p
没有过滤器的参数或类似的东西。所有这些起初可能有点令人困惑;如果是这样,也许它有助于将p ** Vect p a
视为长度未知的" Vector
的替代品"类型。