【发布时间】:2016-12-16 15:00:24
【问题描述】:
我正在尝试在 Idris 中实现类似功能队列的东西,但它携带类型中的元素数量 - 例如 Queue ty n m (n+m) 其中n 是一个 Vect n ty、@987654325 中的元素数量@ 是第二个Vect m ty 中的元素,(n+m) 是总元素。
问题是,在将这些大小作为隐式参数进行操作时,我遇到了应用重写规则的问题:
module Queue
import Data.Vect as V
data Queue : Type -> Nat -> Nat -> Nat -> Type where
mkQueue : (front : V.Vect n ty)
-> (back : V.Vect m ty)
-> Queue ty n m (n + m)
%name Queue queue
top : Queue ty n m (S k) -> ty
top {n = S j} {m} {k = j + m} (mkQueue front back) =
V.head front
top {n = Z} {m = S j} {k = j} (mkQueue front back) =
V.head $ V.reverse back
bottom : Queue ty n m (S k) -> ty
bottom {m = S j} {n} {k = n + j} (mkQueue front back) =
?some_rewrite_1 (V.head back)
bottom {m = Z} {n = S j} {k = j} (mkQueue front back) =
?some_rewrite_2 (V.head $ V.reverse front)
top 有效,但 bottom 无效。看来我需要以某种方式提供plusZeroRightNeutral 和plusRightSuccRight 重写,但我不确定将它们放在哪里,或者是否有其他选择。以下是错误消息:
bottom 第一行出错:
Type mismatch between
Queue ty n (S j) (n + S j) (Type of mkQueue front back)
and
Queue ty n (S j) (S (n + j)) (Expected type)
Specifically:
Type mismatch between
plus n (S j)
and
S (n + j)
bottom第二行出错:
Type mismatch between
Queue ty (S j) 0 (S j + 0) (Type of mkQueue front back)
and
Queue ty (S j) 0 (S j) (Expected type)
Specifically:
Type mismatch between
plus (S j) 0
and
S j
单个尺寸告诉我何时需要旋转两个Vects,而整体尺寸告诉我何时我有一个空的和非空的Queue,所以我确实想跟踪所有信息,如果可能。
【问题讨论】:
-
作为备注,我不会将
front/back大小添加到类型中,只是总大小;我认为前者是应该从客户端代码中隐藏的实现/表示细节。 -
@Cactus:我一直在将我的代码移到那种格式,这样我就只有
Queue ty k,其中MkQueue中的k仍然是(n + m),基于大小Vects 因为这是我要保证的不变量。但是,我遇到的问题是,我无法将{n}和{m}作为top和bottom的正确位置引入。仍在研究这个问题....