如何将不同类型的东西放入列表中,用字符串标记?

时间:2018-01-09 14:43:21

标签: idris dependent-type

我试图将不同类型的内容放入列表中,用字符串标记。

我想要的是这样的:

arr1 : ?what_should_that_be
arr1 = [("num" ** 1), ("str" ** "hello")]

所以我试图证明我作为标签提供的内容实际上是一个有效的标签(通过提供IsTag tag的证明),但似乎编译器没有得到它,所以应该怎样我现在呢?

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

total
typeOf : (tag : String) -> {auto prf: IsTag tag} -> Type
typeOf _ {prf = NumIsTag} = Int
typeOf _ {prf = StrIsTag} = String

arr1 : List (tag : String ** typeOf tag)
arr1 = [("num" ** 1), ("str" ** "hello")]

最终会出现以下错误消息:

When checking type of Main.arr1:
When checking argument prf to Main.typeOf:
        Can't find a value of type
                IsTag tag

我认为此错误消息暗示arr1类型错误,但它应该具有哪种类型?

2 个答案:

答案 0 :(得分:1)

所以你想说服Idris以下是一个有效的类型:

List (tag : String ** typeOf tag)

typeOf函数有两个参数(其中一个参数应该由Idris自己推断)。现在,让我们假装第二个参数是明确的。你会如何手工编写typeOf申请表?

List (tag : String ** typeOf tag <proof>)

但此时您对tag的所有了解都是String,因此您无法提供该证明 - 但是没有足够的信息可供使用。

答案 1 :(得分:1)

我觉得有效:

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

total
typeOf : (tag : String) -> Type
typeOf "num" = Int
typeOf "str" = String
typeOf _ = Void

arr1 : List (tag : String ** typeOf tag)
arr1 = [("num" ** 1), ("str" ** "hello")]

我没有尝试证明代码有效,而是使用Void作为占位符,因此不会创建无效对。