blo*_*rat 6 dependent-type idris
我有一个表示算术运算符的和类型:
data Operator = Add | Substract | Multiply | Divide
Run Code Online (Sandbox Code Playgroud)
我正在尝试为它编写解析器.为此,我需要一份详尽的所有运营商名单.
在Haskell中,我将使用deriving (Enum, Bounded)以下StackOverflow问题中的建议:获取Haskell中所有可能的数据类型值的列表
不幸的是,问题#19所建议的伊德里斯似乎没有这样的机制.大卫·克里斯蒂安森正在就这个问题进行一些正在进行的工作,所以希望将来情况会有所改善:david-christiansen/derive-all-the-instances
来自Scala,我习惯手动列出元素,所以我很自然地想出了以下内容:
Operators : Vect 4 Operator
Operators = [Add, Substract, Multiply, Divide]
Run Code Online (Sandbox Code Playgroud)
为了确保Operators包含所有元素,我添加了以下证明:
total
opInOps : Elem op Operators
opInOps {op = Add} = Here
opInOps {op = Substract} = There Here
opInOps {op = Multiply} = There (There Here)
opInOps {op = Divide} = There (There (There Here))
Run Code Online (Sandbox Code Playgroud)
因此,如果我在Operator不添加元素的情况下添加元素Operators,则整体检查器会抱怨:
Parsers.opInOps is not total as there are missing cases
Run Code Online (Sandbox Code Playgroud)
它做的工作,但它是很多样板.我错过了什么?有没有更好的方法呢?
可以选择使用该语言的特性(例如详细反射)来获取所有构造函数的列表。
这是解决这个特定问题的一个非常愚蠢的方法(我发布这个是因为目前的文档非常稀缺):
%language ElabReflection
data Operator = Add | Subtract | Multiply | Divide
constrsOfOperator : Elab ()
constrsOfOperator =
do (MkDatatype _ _ _ constrs) <- lookupDatatypeExact `{Operator}
loop $ map fst constrs
where loop : List TTName -> Elab ()
loop [] =
do fill `([] : List Operator); solve
loop (c :: cs) =
do [x, xs] <- apply `(List.(::) : Operator -> List Operator -> List Operator) [False, False]
solve
focus x; fill (Var c); solve
focus xs
loop cs
allOperators : List Operator
allOperators = %runElab constrsOfOperator
Run Code Online (Sandbox Code Playgroud)
一些评论: