依存类型中的案例表达式无法在Idris中正常工作

时间:2019-02-08 17:16:05

标签: idris

我正在尝试将一小部分PureScript代码移植到Idris,在这种情况下,可能会应用依赖类型,并偶然遇到在依赖类型中使用case的情况。

因为这是有效的(简体):

data ValidInvoice3 : (ft : FeeType) -> Type where
  MkVI3 : ValidInvoice3 ft

以下为什么不输入检查?

-- BROKEN
data ValidInvoice4 : (ft : FeeType) -> Type where
  MkVI4 : case ft of
            FeeMarkupHidden => ValidInvoice4 ft -- simplified;
            FeeExplicit     => ValidInvoice4 ft -- more elaborate example below

如果您有兴趣为什么我要研究此内容:这里有一些更详细的示例代码:

module DependentWithCase

data FeeType = FeeMarkupHidden | FeeExplicit

data Fee : (ft : FeeType) -> Type where
  MkFee : Fee ft -- simplified

data ValidArticle : (ft : FeeType) -> Type where
  MkVA : ValidArticle ft -- simplified

这里是如何使用case表达式成功确定“发票”的依存类型并在FeeType上建立索引,以确定是否将费用作为显式参数添加(在实际代码中,在这种情况下,“文章”类型具有一个“标记”部分,我在这里将其遗漏了;通过这种方式,我可以确定“标记”仅开票一次):

data ValidInvoice : (ft : FeeType) -> Type where
  MkVI : ValidArticle ft ->
         case ft of FeeMarkupHidden => Unit; FeeExplicit => Fee ft;
         ->
         ValidInvoice ft

因此,您会看到发票数据类型(在实际代码中,商品类型也是如此)取决于费用类型。

但是,与其使用隐藏在构造函数内部的case表达式,不如让它看起来像这种类型的同义词(当然,它没有构造函数;但这实质上是它在PureScript代码中的读取方式,但是而是使用具有单独构造函数的sum类型而不是此处的依赖类型(在FeeType上建立索引)。这对我来说更具可读性(尤其是在实际代码中)。

ValidInvoice2 : (ft : FeeType) -> Type
ValidInvoice2 FeeMarkupHidden = ValidArticle FeeMarkupHidden -> Unit            -> ValidInvoice2 FeeMarkupHidden
ValidInvoice2 FeeExplicit     = ValidArticle FeeExplicit     -> Fee FeeExplicit -> ValidInvoice2 FeeExplicit

那么ValidInvoice4为什么不进行类型检查?我写错了吗?还是期望有些东西行不通?

1 个答案:

答案 0 :(得分:0)

看来Idris并未注意到case语句的任何一个分支都会导致ValidInvoice4。它还不会在相似位置评估函数。您几乎总是可以做一些稍有不同的事情,但是得到相同的结果。

考虑您要完成的工作,我建议将Fee设为索引FeeType的{​​{1}}-简化整个过程:

Maybe