Vector Idris-向量队列和重写规则

Vector Idris-向量队列和重写规则,vector,queue,idris,Vector,Queue,Idris,我试图在Idris中实现类似于函数队列的东西,但它携带类型中的元素数量-例如queue ty n m(n+m),其中n是一个Vect n ty中的元素数量,m是第二个Vect m ty中的元素,以及(n+m)是元素总数 问题是,在将这些大小作为隐式参数处理时,我遇到了应用重写规则的问题: module Queue import Data.Vect as V data Queue : Type -> Nat -> Nat -> Nat -> Type where

我试图在Idris中实现类似于函数队列的东西,但它携带类型中的元素数量-例如
queue ty n m(n+m)
,其中
n
是一个
Vect n ty
中的元素数量,
m
是第二个
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
重写,但我不确定这些内容放在哪里,或者是否有其他选项。以下是错误消息:

底部
的第一行出错

         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)
         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
底部第二行出现错误:

         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)
         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

单个大小告诉我何时需要旋转两个
Vect
s,总大小告诉我何时有空的
队列与非空的
队列
,因此如果可能,我确实希望跟踪所有信息。

解决此问题的一种可能方法是同时销毁
n
。这一次,Idris明白最后一个参数不是零,它基本上是在抱怨:

total
bottom : Queue ty n m (S k) -> ty
bottom {m = S m} {n = S n} (MkQueue _ back) = V.head back
bottom {m = S m} {n = Z}   (MkQueue _ back) = V.head back
bottom {m = Z}   {n = S n} (MkQueue front _) = V.head $ V.reverse front
bottom {m = Z}   {n = Z}   (MkQueue _ _) impossible
作为旁注,我建议将
top
函数设为总计:

total
top : Queue ty n m (S k) -> ty
top {n = S n}           (MkQueue front _) = V.head front
top {n = Z}   {m = S m} (MkQueue _ back) = V.head $ V.reverse back
top {n = Z}   {m = Z}   (MkQueue _ _) impossible

非常好-工作完美,解决了问题,关于总体的注释也很有用。谢谢作为说明,我不会将
前面的
/
后面的
大小添加到类型中,只添加总大小;我认为前者是一个实现/表示细节,应该对客户机代码隐藏。@Cactus:我一直在将代码移到该格式,这样我就可以使用
Queue tyk
,其中
MkQueue
中的
k
仍然是
(n+m)
基于
Vect
s的大小,因为我想保证这是一个不变量。然而,我的问题是,我不能把
{n}
{m}
放在
顶部
底部
的正确位置。仍在处理该问题…相关:。