使用从属对

时间:2018-01-08 16:17:56

标签: idris dependent-type

我写下这个:

data IsTag : String -> Type where
    NumIsTag : IsTag "num"
    StrIsTag : IsTag "str"

arr1 : List (tag : String ** (IsTag tag, (case tag of "num" => Int; "str" => String)))
arr1 = [("num" ** (NumIsTag, 1)), ("str" ** (StrIsTag, "hello"))]

并获取以下持有错误消息:

When checking right hand side of arr1 with expected type
        List (tag : String **
              (IsTag tag, case tag of   "num" => Int "str" => String))

When checking argument b to constructor Builtins.MkPair:
        case "num" of
          "num" => Int
          "str" => String is not a numeric type

但我无法理解,为什么case "num" of "num" => Int; "str" => String不是数字类型?它不等于Int

1 个答案:

答案 0 :(得分:2)

不是,因为Idris在类型检查期间不会减少部分(非全部)函数。

如果你的字符串不等于"num" / "str",那么你有一个很好的默认类型,那么你可以这样:

total
tagToType : String -> Type
tagToType "num" = Int
tagToType "str" = String
tagToType _ = ?defaultType

arr1 : List (tag : String ** (IsTag tag, tagToType tag))
arr1 = [("num" ** (NumIsTag, 1)), ("str" ** (StrIsTag, "hello"))]

另一种选择是如此定义:

total
tagToType : IsTag s -> Type
tagToType NumIsTag = Int
tagToType StrIsTag = String

arr1 : List (tag : String ** istag : IsTag tag ** tagToType istag)
arr1 = [("num" ** NumIsTag ** 1), ("str" ** StrIsTag ** "hello")]