Idris矢量与链接列表

时间:2014-12-18 16:42:01

标签: vector linked-list algebraic-data-types idris

Idris在矢量引擎下做了什么样的优化吗?因为从它的外观来看,Idris向量只是一个已知大小的链表(在编译时已知)。事实上,一般来说,你似乎可以表达以下等价物(我在语法上有点猜测):

Vector : Nat -> Type -> Type
Vector n t = (l: List t ** length l = n)

因此,虽然这在防止范围误差方面很好,但是矢量的真正优势(在该术语的传统用法中)是在性能方面;特别是O(1)随机访问。似乎idris向量不支持这个(你如何编写索引函数来获得这种性能?)。

  • 假设没有任何巫术(正如Nat所述)重新配置Vector,那么Idris中是否有随机访问数据类型?
  • 如何在代数类型系统中定义这样的东西?当然,似乎就像不可能以归纳的方式定义它。
  • 在类似Idris的类型系统中,是否有可能创建支持O(1)随机访问的数据类型,知道其长度,以便所有访问都可证明是有效的? (Haskell有数组样式的向量,但它们的具体实现对普通用户来说是不透明的,包括我)

2 个答案:

答案 0 :(得分:15)

它无法优化Vector查找(至少在撰写此答案时)。

这不是因为这样做有任何困难,实际上,更多是因为我宁愿有一些用于编写这种优化的通用框架,而不是硬编码它们。不可否认,我们已经对Nat进行了硬编码优化,但我仍然不希望以临时方式添加更多负载。

根据您的实际需要,实验性的唯一性类型系统可能会有所帮助,因为您可以在引擎盖下有一个低级可变的东西,并且仍然可以以纯粹的方式安全有效地访问和更新在高级语言。我们会看到......

答案 1 :(得分:2)

Edwin has the definitive answers on what Idris currently does.但是,如果您正在寻找在某些情况下可以自然地优化为常数查找的内容,以下可能是朝着正确方向迈出的一步。

对于编译时固定大小的向量(即,不在lambda下,不在顶层长度参数化),以下结构为您提供向量和查找函数,对于任何固定的具体长度,可以编译 - 时间归一化为函数,这些函数应该在某种程度上可以直接优化为常数时间函数。 (对不起,代码在Coq;我目前还没有Idris的工作版本,并且不太了解。如果有人建议,我很乐意用Idris代码替换它正确的语法,例如,在评论中。)

Fixpoint vector (n : nat) (A : Type) :=
  match n return Type with
    | 0 => unit
    | S n' => (A * vector n' A)%type
  end.
Definition nil {A} : vector 0 A := tt.
Definition cons {n} {A : Prop} (x : A) (xs : vector n A) : vector (S n) A
  := (x, xs).
Fixpoint get {n} {A : Prop} (m : nat) (default : A) (v : vector n A) {struct n} : A
  := match n as n return vector n A -> A with
       | 0 => fun _ => default
       | S n' => match m with
                   | 0 => fun v => fst v
                   | S m' => fun v => @get n' A m' default (snd v)
                 end
     end v.

这个想法是,对于任何固定的 n get的正常形式是非递归的,因此编译器可以假设将其编译为运行时独立的函数 n 恰好是什么。