Idris在矢量引擎下做了什么样的优化吗?因为从它的外观来看,Idris向量只是一个已知大小的链表(在编译时已知)。事实上,一般来说,你似乎可以表达以下等价物(我在语法上有点猜测):
Vector : Nat -> Type -> Type
Vector n t = (l: List t ** length l = n)
因此,虽然这在防止范围误差方面很好,但是矢量的真正优势(在该术语的传统用法中)是在性能方面;特别是O(1)随机访问。似乎idris向量不支持这个(你如何编写索引函数来获得这种性能?)。
Nat
所述)重新配置Vector
,那么Idris中是否有随机访问数据类型?答案 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 恰好是什么。