Types Idris印章类型

Types Idris印章类型,types,functional-programming,idris,dependent-type,Types,Functional Programming,Idris,Dependent Type,我正试图在Idris中编写一个chop函数。Haskell等效设备的外观如下所示: chop :: Int -> [t] -> [[t]] chop n [] = [] chop n v = take n v : chop n (drop n v) 我在Idris中的初始尝试如下所示: chop : (n : Nat) -> Vect (k * n) a -> Vect k (Vect n a) chop n Nil = Nil chop n v = (take n v

我正试图在Idris中编写一个
chop
函数。Haskell等效设备的外观如下所示:

chop :: Int -> [t] -> [[t]]
chop n [] = []
chop n v = take n v : chop n (drop n v)
我在Idris中的初始尝试如下所示:

chop : (n : Nat) -> Vect (k * n) a -> Vect k (Vect n a)
chop n Nil = Nil
chop n v = (take n v) :: (chop n (drop n v))
类型检查错误:

Type mismatch between
               Vect 0 a (Type of [])
       and
               Vect (mult k n) a (Expected type)

       Specifically:
               Type mismatch between
                       0
               and
                       mult k n

k
仍然可以设置为参数,即
chop{k=3}Z[]
将导致
[[],[],[]:Vect 3(Vect Z a)
。您的实现将返回
chop n Nil=[]
,因此Idris的类型系统会正确地进行投诉。:-)

你需要考虑<代码> k>代码>:

chop : (n : Nat) -> Vect (k * n) a -> Vect k (Vect n a)
chop {k} n v = ?hole
如果您想要实际实施,这里有一个扰流器:

它和你的很相似。因为
mult
在第一个参数上递归(
k
,在这种情况下),
chop
的递归也应该跟随
k

chop{k=Z}n v=[]

chop{k=(sk)}nv=take n v::chop n(drop n v)

另一种方法是指定所需的块数,而不是每个块的大小

chop' : (k : Nat) -> Vect (k * n) a -> Vect k (Vect n a)
chop' Z v = []
chop' {n} (S k) v = take n v :: chop k (drop n v)

n
需要在范围内调用
take
drop

我理解
chop{k=Z}nv=[]
,但是
chop{k=(sk)}nv=take nv::chop n(drop nv)
那么你能详细说明什么是难以理解的吗?如何从
chop{k=sk}…=?hole
到实现?对于
n>0
,不是只有一个有效的
k
值吗?是否有必要重写chop,以便不必指定k。如果定义了
k
k=Z
),那么您也应该在其他情况下定义它。否则,Idris可能知道也可能不知道
k!=Z
在其他情况下。另外,因为
k
是要递归的参数(正如
Vect k…
是结果),所以需要对其进行拆分。您可以使用另一个函数删除
n
,如
chop':(k:Nat)->Vect(k*n)a->Vect k(Vect n a)
。我不确定
chop'
会是什么样子