Idris确定结果矢量长度

时间:2017-10-02 13:32:14

标签: dependent-type idris

在Idris中,如果我想删除基于谓词的元素,则会filterdropWhiletakeWhile。但是,所有这些函数都返回一个从属对(n : Nat ** Vect n elem)

是否有任何函数以Vect类型返回?

我能想到的是:

  1. 将从属对转换为Vect

  2. 在转换后实现一个指示长度向量的类型(我不知道如何),例如HereThere

  3. 对于上述想法,1(转换每个结果)或2(设计每个类型以表示结果向量长度)似乎相当麻烦。

    有没有更好的方法来实现这种行为?

    dropElem : String -> Vect n String -> Vect ?resultLen String

1 个答案:

答案 0 :(得分:1)

也许这就是你要找的东西?

import Data.Vect

count: (ty -> Bool) -> Vect n ty -> Nat
count f [] = 0
count f (x::xs) with (f x)
    | False = count f xs
    | True = 1 + count f xs

%hint
countLemma: {v: Vect n ty} -> count f v `LTE` n
countLemma {v=[]} = LTEZero
countLemma {v=x::xs} {f} with (f x)
    | False = lteSuccRight countLemma
    | True = LTESucc countLemma

filter: (f: ty -> Bool) -> (v: Vect n ty) -> Vect (count f v) ty
filter f [] = []
filter f (x::xs) with (f x)
    | False = filter f xs
    | True = x::filter f xs

然后你这样做:

dropElem: (s: String) -> (v: Vect n String) -> Vect (count ((/=) s) v) String
dropElem s = filter ((/=) s)

您甚至可以重复使用现有的filter实施:

count: (ty -> Bool) -> Vect n ty -> Nat
count f v = fst $ filter f v

filter: (f: ty -> Bool) -> (v: Vect n ty) -> Vect (count f v) ty
filter f v = snd $ filter f v