Types Idris印章类型
我正试图在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
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'
会是什么样子