问题
I'm trying to put things with different type into a list, tagged by string.
What I want is something like that:
arr1 : ?what_should_that_be
arr1 = [("num" ** 1), ("str" ** "hello")]
So I tried to prove that what I given as a tag is actually a valid tag (by providing a proof of IsTag tag
), but it seems that the compiler didn't get it, so what should I do now?
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")]
It ends up with the following error message:
When checking type of Main.arr1:
When checking argument prf to Main.typeOf:
Can't find a value of type
IsTag tag
I think this error message implies that arr1
has a wrong type, but what type should it have?
回答1:
So you want to convince Idris the following is a valid type:
List (tag : String ** typeOf tag)
The typeOf
function has two parameters (one of which is supposed to be inferable by Idris on its own). Now, let's pretend for a moment that the second parameter is explicit. How would you write typeOf
application by hand?
List (tag : String ** typeOf tag <proof>)
But at this point all you know about tag
is that it is a String
so you cannot provide that proof -- there is just not enough information available.
回答2:
I find that works:
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")]
Instead of trying to prove that the tag is valid, I use Void
as a placeholder, so that invalid pair will not be created.
来源:https://stackoverflow.com/questions/48170626/how-to-put-things-with-different-type-into-a-list-tagged-by-string