在 Idris 的接口内定义数据类型
Define a data type inside an interface in Idris
我希望创建一个 class 类型,可以证明某个元素是正数还是负数,或者是零。我创建了一个接口:
interface Signed t where
data Positive : t -> Type
data Negative : t -> type
data IsZero : t -> Type
现在我想为 Nat
创建一个实现,但我无法计算出它的语法。这例如不起作用:
Signed Nat where
data Positive : Nat -> Type where
PosNat : (n : Nat) -> Positive (S n)
data Negative : Nat -> Type where
NegNat : Void -> Negative Nat
data IsZero : Nat -> Type
ZZero : IsZero Z
我在实现中 data Positive
出现 not end of block
错误。但是,省略 data Positive...
行也不起作用。伊德里斯然后说 method Positive is undefined
。那么如何在接口中实现类型?
此外,以下似乎不起作用:
data NonZero : Signed t => (a : t) -> Type where
PositiveNonZero : Signed t => Positive a -> NonZero a
NegativeNonZero : Signed t => Negative a -> NonZero a
伊德里斯说:Can't find implementation for Signed phTy
。那么做这一切的正确语法是什么?也许我做错了?我知道 Data.So
的存在,但经过几次实验后,它对我来说似乎很复杂,我更愿意使用手动定义的证明,这要简单得多。除了 Data.So
的文档本身声明它应该真正与基元一起使用。
看来我终于明白了。这是有效的代码:
interface Signed t where
data Positive : t -> Type
data Negative : t -> Type
data IsZero : t -> Type
data NonZero : t -> Type where
PositiveNonZero : Signed t => {a : t} -> Positive a -> NonZero a
NegativeNonZero : Signed t => {a : t} -> Negative a -> NonZero a
data PositNat : Nat -> Type where
PN : (n : Nat) -> PositNat (S n)
data NegatNat : Nat -> Type where
NN : Void -> NegatNat n
data ZeroNat : Nat -> Type where
ZN : ZeroNat Z
Signed Nat where
Positive n = PositNat n
Negative n = NegatNat n
IsZero = ZeroNat
oneNonZero : NonZero (S Z)
oneNonZero = PositiveNonZero (PN 0)
因此,为了交付接口要求的数据类型的实现,您必须单独定义它,然后才说接口要求的类型等于您定义的类型。
至于依赖于接口的类型,你只需要指定一个额外的隐式参数来声明a
的类型(不幸的是,不能写成Positive (a : t) -> NonZero a
。你实际上似乎需要隐含的。除此之外,它似乎工作正常,所以我相信这就是问题的答案。当然,欢迎更多了解 Idris 方式的人提供任何额外的输入。
我希望创建一个 class 类型,可以证明某个元素是正数还是负数,或者是零。我创建了一个接口:
interface Signed t where
data Positive : t -> Type
data Negative : t -> type
data IsZero : t -> Type
现在我想为 Nat
创建一个实现,但我无法计算出它的语法。这例如不起作用:
Signed Nat where
data Positive : Nat -> Type where
PosNat : (n : Nat) -> Positive (S n)
data Negative : Nat -> Type where
NegNat : Void -> Negative Nat
data IsZero : Nat -> Type
ZZero : IsZero Z
我在实现中 data Positive
出现 not end of block
错误。但是,省略 data Positive...
行也不起作用。伊德里斯然后说 method Positive is undefined
。那么如何在接口中实现类型?
此外,以下似乎不起作用:
data NonZero : Signed t => (a : t) -> Type where
PositiveNonZero : Signed t => Positive a -> NonZero a
NegativeNonZero : Signed t => Negative a -> NonZero a
伊德里斯说:Can't find implementation for Signed phTy
。那么做这一切的正确语法是什么?也许我做错了?我知道 Data.So
的存在,但经过几次实验后,它对我来说似乎很复杂,我更愿意使用手动定义的证明,这要简单得多。除了 Data.So
的文档本身声明它应该真正与基元一起使用。
看来我终于明白了。这是有效的代码:
interface Signed t where
data Positive : t -> Type
data Negative : t -> Type
data IsZero : t -> Type
data NonZero : t -> Type where
PositiveNonZero : Signed t => {a : t} -> Positive a -> NonZero a
NegativeNonZero : Signed t => {a : t} -> Negative a -> NonZero a
data PositNat : Nat -> Type where
PN : (n : Nat) -> PositNat (S n)
data NegatNat : Nat -> Type where
NN : Void -> NegatNat n
data ZeroNat : Nat -> Type where
ZN : ZeroNat Z
Signed Nat where
Positive n = PositNat n
Negative n = NegatNat n
IsZero = ZeroNat
oneNonZero : NonZero (S Z)
oneNonZero = PositiveNonZero (PN 0)
因此,为了交付接口要求的数据类型的实现,您必须单独定义它,然后才说接口要求的类型等于您定义的类型。
至于依赖于接口的类型,你只需要指定一个额外的隐式参数来声明a
的类型(不幸的是,不能写成Positive (a : t) -> NonZero a
。你实际上似乎需要隐含的。除此之外,它似乎工作正常,所以我相信这就是问题的答案。当然,欢迎更多了解 Idris 方式的人提供任何额外的输入。