在Idris的界面内定义数据类型

时间:2019-02-19 07:09:33

标签: types interface idris

我希望创建一类类型,可以证明某个元素为正或负或零。我创建了一个界面:

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

我收到not end of block错误,其中data Positive代表实现。但是,省略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

伊德里斯(Idris)说:Can't find implementation for Signed phTy。那么做这一切的正确语法是什么?也许我做错了方法?我知道Data.So的存在,但是经过几次实验后,这对我来说似乎很复杂,我更喜欢使用手动定义的证明,这要简单得多。除了Data.So的文档本身指出,它实际上应该与基元一起使用。

1 个答案:

答案 0 :(得分:0)

看来我终于想通了。这是有效的代码:

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方式学到的人的任何其他投入。