Idris - 矢量队列和重写规则

时间:2016-12-16 15:00:25

标签: vector queue idris

我试图在Idris中实现像功能队列这样的东西,但它带有类型中的元素数量 - 例如Queue ty n m (n+m)其中n是一个元素的数量Vect n tym是第二个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没有。我似乎需要提供plusZeroRightNeutralplusRightSuccRight重写,但我不知道在哪里放这些,或者是否可能有其他选项。以下是错误消息:

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

个别尺码告诉我何时需要旋转两个Vect s,整体尺寸告诉我何时有空的{非空Queue,所以我确实想跟踪如果可能的话,所有的信息。

1 个答案:

答案 0 :(得分:2)

解决此问题的一种可能方法是破坏n。这次伊德里斯明白最后一个论点不是零,这基本上是在抱怨:

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