idris - 如何创建仅接受类型构造函数子集的函数?

标签 idris

假设我有一个像这样的类型:

data Foo = Bar String | Baz | Qux String

我想要一个这样的功能:
get : Foo -> String
get (Bar s) = s
get (Qux s) = s

如所写,这可以编译,但不是总的,因为有遗漏的情况。换句话说,get Baz被视为一个漏洞,而不是不进行类型检查的表达式。

我想用某种指定值必须是Fooget的东西来替换Bar类型签名中的Qux如何表达Foo类型的子集?

最佳答案

您还可以混合使用两种方法(由Kim Stiebel和Anton Trunov编写)并构造一个辅助数据类型。只能使用OnlyBarAndQuxBar的值构造Qux类型。对于idris,然后可以在调用get的情况下自动推断出一个证明:

module FooMe

data Foo = Bar String | Baz | Qux String

data OnlyBarAndQux: Foo -> Type where
    BarEy: OnlyBarAndQux (Bar s)
    QuxEx: OnlyBarAndQux (Qux s)

||| get a string from a Bar or Qux
total
get: (f: Foo) -> {auto prf : OnlyBarAndQux f} -> String
get (Bar s) {prf = BarEy} = s
get (Qux s) {prf = QuxEx} = s

-- Tests

test1: get $ Bar "hello" = "hello"
test1 = Refl

test2: get $ Qux "hello" = "hello"
test2 = Refl

-- does not compile
-- test3: get $ Baz = "hello"

关于idris - 如何创建仅接受类型构造函数子集的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45702926/

相关文章:

parsing - 在 Idris 中使用类型谓词生成运行时证明

仅数学证明助理

haskell - 如何在 Haskell 中编写简单的依赖类型函数?

implicit - GADT 数据构造函数参数在 Idris 中如何工作?

idris - Idris 中的常量

polymorphism - Profunctor Iso 不进行类型检查

functional-programming - 为什么没有明确类型的这个 Idris 片段类型检查?

idris - idris 公设

list - 非空列表comonad

idris - 隐式参数的顺序如何影响 idris?