我试图在Idris中创建大小为n的元组:
module NTuple
data Tuple : Vect n Type -> Type where
EmptyTuple : Tuple Nil
TupleItem : a -> Tuple types -> Tuple (a :: types)
mapN : {types : Vect n Type} -> (i : Fin (S n)) -> (a -> b) -> Tuple (insertAt i a types) -> Tuple (insertAt i b types)
mapN fZ f (TupleItem x xs) = TupleItem (f x) xs
mapN (fS i) f (TupleItem x xs) = TupleItem x (mapN i f xs)
但是我在最后一行收到了这个错误:
When elaborating left hand side of mapN: When elaborating an application of NTuple.mapN: Can't unify Tuple (a :: types) with Tuple (insertAt (fS i) a types) Specifically: Can't unify a :: types with insertAt (fS i) a types
有没有办法让这个功能起作用?
答案 0 :(得分:2)
问题是insertAt (FS i) a types
如果不了解types
,就无法减少types = t :: ts
。如果我们知道t :: insertAt i ts
,则可以将其缩减为mapN
。
但是在types
的第二个案例中,我们做知道FS i
完全符合这种形式:
n = S m
m
某些types
... Vect (S m) Type
参数的类型为t :: ts
insertAt (FS i) a types
!一旦我们向Idris指出这一点,我们很乐意减少mapN : {types : Vect n Type} -> (i : Fin (S n)) -> (a -> b) -> Tuple (insertAt i a types) -> Tuple (insertAt i b types)
mapN FZ f (TupleItem x xs) = TupleItem (f x) xs
mapN {types = _ :: _} (FS i) f (TupleItem x xs) = TupleItem x (mapN i f xs)
mapN {types = []} (FS i) _ _ = absurd i
因此您的代码类型检查:
{{1}}