Я относительно новичок в idris и зависимых типах, и я столкнулся со следующей проблемой - я создал собственный тип данных, похожий на векторы:
infixr 1 :::
data TupleVect : Nat -> Nat -> Type -> Type where
Empty : TupleVect Z Z a
(:::) : (Vect o a, Vect p a) ->
TupleVect n m a ->
TupleVect (n+o) (m+p) a
exampleTupleVect : TupleVect 5 4 Int
exampleTupleVect = ([1,2], [1]) ::: ([3,4],[2,3]) ::: ([5], [4]) ::: Empty
Он индуктивно создается путем добавления кортежей векторов и индексируетсясуммой длин векторов в каждой позиции кортежа.
Я попытался реализовать функцию карты для моего типа данных:
tupleVectMap : ((Vect k a, Vect l a) -> (Vect k b, Vect l b)) ->
TupleVect n m a -> TupleVect n m b
tupleVectMap f Empty = Empty
tupleVectMap f (x ::: xs) = let fail = f x
in ?rest_of_definition
Это приводит к следующей ошибке типа:
|
20 | tupleVectMap f (x ::: xs) = let fail = f x
| ~~~~~~~~~~~~~~ ...
When checking right hand side of tupleVectMap with expected type
TupleVect (n + o) (m + p) b
Type mismatch between
(Vect o a, Vect p a)
and
(Vect k a, Vect l a)
Кажется, что средство проверки типов не может объединить длины векторов в извлеченном кортеже x и необходимые длины в аргументе f.Однако я не понимаю, почему это так, поскольку k и l являются просто именами типов, указывающими, что f не меняет длину данных векторов.
Я еще более озадачен, поскольку следующие проверки типов:
tupleVectMap' : TupleVect n m a -> TupleVect n m b
tupleVectMap' Empty = Empty
tupleVectMap' (x ::: xs) =
let nonfail = f x
in ?rest_of_definition
where
f : ((Vect k a, Vect l a) -> (Vect k b, Vect l b))
Здесь f имеет точно такую же сигнатуру типа.Единственная разница в том, что f определяется локально.