是否可以为Idris中的接口创建可确定的属性,以供在接口内部使用?
例如-假设我们有一个简单的接口Foo和一个数据类型 FooTypeEmpty表示给定foo对象为“空”(定义为“由两个零索引”)的语句:
interface Foo (foo : Nat -> Nat -> Type -> Type) where
mkEmpty : foo 0 0 a
isEmpty : (f : foo n m a) -> Bool
data FooTypeEmpty : (Foo foo) => foo n m a -> Type where
MkFooTypeEmpty : (Foo foo) => (f : foo 0 0 a) -> FooTypeEmpty f
是否可以将isEmpty方法赋予以下类型?:
isEmpty : (f : foo n m a) -> Dec (FooTypeEmpty f)
也就是说,使用FooTypeEmpty以便isEmpty返回证明(或矛盾)给定的foo对象为“空”?
我尝试了使用互斥块,但这不会进行类型检查:
mutual
interface Foo (foo : Nat -> Nat -> Type -> Type) where
mkEmpty : foo 0 0 a
isEmpty : (f : foo n m a) -> Dec (FooTypeEmpty f)
data FooTypeEmpty : (Foo foo) => foo n m a -> Type where
FTE : (Foo foo) => (f : foo 0 0 a) -> FooTypeEmpty f
更笼统地说:是否有可能在所有实现中都有效/必需的接口方法中加入证明?
答案 0 :(得分:2)
您无法访问他定义中正在构造的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
的唯一功能是使用证明本身的功能。