简体   繁体   English

Idris解析器组合器GADT

[英]Idris parser combinator GADT

I am currently working on implementing a simple parser combinator library in Idris to learn the language and better understand type systems in general, but am having some trouble wrapping my head around how GADTs are declared and used. 我目前正在Idris中实现一个简单的解析器组合器库,以学习该语言并总体上更好地理解类型系统,但是在围绕如何声明和使用GADT方面遇到一些麻烦。 The parser data type that I am trying to formulate looks like (in Haskell): type Parser a = String -> [(a,String)] , from this paper. 我试图配制的样子(在Haskell)解析器数据类型: type Parser a = String -> [(a,String)] ,从纸张。 Basically, the type is a function that takes a string and returns a list. 基本上,类型是一个接受字符串并返回列表的函数。

In Idris I have: 在伊德里斯,我有:

data Parser : Type -> Type where
    fail : a -> (String -> [])
    pass : a -> (String -> [(a,String)])

where the fail instance is a parser that always fails (ie- will be a function that always returns the empty list) and the pass instance is a parser that consumed some symbol. 其中fail实例是一个总是失败的解析器(即-将是一个始终返回空列表的函数),而pass实例是一个消耗了一些符号的解析器。 When loading the above into the interpreter, I get an error that there is a type mismatch between List elem and the expected type Type . 将上述内容加载到解释器时,我收到一个错误,即List elem和预期的Type之间存在类型不匹配。 But when I check the returned type of the parser in the repl with :t String -> List Type I get Type , which looks like it should work. 但是,当我用:t String -> List Type String- :t String -> List Type在repl中检查解析器的返回类型时,我得到Type ,看起来应该可以工作。

I would be very grateful if anyone could give a good explanation of why this data declaration does not work, or a better alternative to representing the parser data type. 如果有人能很好地解释为什么此数据声明不起作用,或者是表示解析器数据类型的更好替代方法,我将不胜感激。

In defining your datatype Parser, the first line is saying this type takes a type and returns a type, in this case it takes an a and returns a Parser a . 在定义数据类型解析器时,第一行表示此类型接受一个类型并返回一个类型,在这种情况下,它接受一个a并返回一个Parser a

So, your constructors should return Parser a . 因此,您的构造函数应返回Parser a

Similar to a List which takes an a and returns a List a . 类似于List接受a并返回List aList a

What you are currently returning in your constructors are not of type Parser - easily seen as nowhere does the word Parser occur on the right hand side. 您当前在构造函数中返回的内容不是Parser类型-很容易看到,因为Parser一词在右侧没有出现。

Beyond that though, I'm not sure how you would best represent this. 除此之外,我不确定您如何最好地表示这一点。 However, there are some parser libraries already written in Idris, looking at these might help ? 但是,已经有一些用Idris编写的解析器库了,看一下这些库是否有帮助? For example, have a look at this list of libraries, parsers are the first ones mentioned :- Idris libraries 例如,看一下此库列表,首先提到的是解析器: -Idris库

In Haskell, 在Haskell,

type Parser a = String -> [(a,String)]

doesn't create a new type, it is merely a type synonym. 不会创建新的类型,它只是类型的同义词。 You can do something similar in Idris as 您可以在Idris中执行类似的操作

Parser : Type -> Type
Parser a = String -> List (a, String)

and then define your helper definitions as simple functions that return Parser a s: 然后将帮助程序定义定义为返回Parser a的简单函数:

fail : Parser a
fail = const []

pass : a -> Parser a
pass x = \s => [(x, s)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM