Вы не можете получить доступ к Foo
, который вы строите в его определении, который понадобится isEmpty
. Интерфейсы - это просто причудливые конструкторы данных, поэтому ваш интерфейс примерно эквивалентен:
MkFoo : (foo : Nat -> Nat -> Type -> Type) ->
(mkEmpty : foo 0 0 a) ->
(isEmpty : ((f : foo n m a) ->
Dec (FooTypeEmpty f {Foo interface=MkFoo foo mkEmpty isEmpty})) ->
Foo foo
Благодаря самоссылке на MkFoo
в isEmpty
, Foo
не будет строго положительным, поэтому не полным.
Так что вам придется заранее определить тип доказательства. Просто используйте тот же аргумент типа:
data FooTypeEmpty : {foo : Nat -> Nat -> Type -> Type} ->
foo n m a -> Type where
FTE : {foo : Nat -> Nat -> Type -> Type} ->
(f : foo 0 0 a) -> FooTypeEmpty f
interface Foo (foo : Nat -> Nat -> Type -> Type) where
mkEmpty : foo 0 0 a
isEmpty : (f : foo n m a) -> Dec (FooTypeEmpty f)
data Bar : Nat -> Nat -> Type -> Type where
Empty : Bar 0 0 a
Foo Bar where
mkEmpty = Empty
isEmpty = \Empty => Yes (FTE Empty)
Если вы хотите доказать некоторые вещи о функциях, данных интерфейсу, просто укажите их в качестве дополнительных аргументов (здесь mkEmpty
):
data FooTypeEmpty : {foo : Nat -> Nat -> Type -> Type} ->
{mkEmpty : foo 0 0 a} ->
foo n m a -> Type where
FTE : {foo : Nat -> Nat -> Type -> Type} ->
{mkEmpty : foo 0 0 a} ->
FooTypeEmpty mkEmpty
interface Foo (foo : Nat -> Nat -> Type -> Type) where
mkEmpty : foo 0 0 a
isEmpty : (f : foo n m a) -> Dec (FooTypeEmpty {mkEmpty} f)
data Bar : Nat -> Nat -> Type -> Type where
Empty : Bar 0 0 a
Foo Bar where
mkEmpty = Empty
isEmpty = \Empty => Yes FTE
Единственная функция, которую вы не можете дать FooTypeEmpty
, - это функция, которая использует само доказательство.