Parsing Idris解析器组合器GADT

Parsing Idris解析器组合器GADT,parsing,types,gadt,idris,Parsing,Types,Gadt,Idris,我目前正致力于在Idris中实现一个简单的解析器组合器库,以学习该语言并更好地理解一般的类型系统,但在理解GADT是如何声明和使用时遇到了一些困难。我试图表述的解析器数据类型类似于(在Haskell中):type parser a=String->[(a,String)],摘自论文。基本上,类型是一个接受字符串并返回列表的函数 在伊德里斯,我有: data Parser : Type -> Type where fail : a -> (String -> [])

我目前正致力于在Idris中实现一个简单的解析器组合器库,以学习该语言并更好地理解一般的类型系统,但在理解GADT是如何声明和使用时遇到了一些困难。我试图表述的解析器数据类型类似于(在Haskell中):
type parser a=String->[(a,String)]
,摘自论文。基本上,类型是一个接受字符串并返回列表的函数

在伊德里斯,我有:

data Parser : Type -> Type where
    fail : a -> (String -> [])
    pass : a -> (String -> [(a,String)])
其中,
fail
实例是一个总是失败的解析器(即,-将是一个总是返回空列表的函数),而
pass
实例是一个使用了一些符号的解析器。当将上述内容加载到解释器中时,我得到一个错误,即
列表元素
与预期类型
类型
之间存在类型不匹配。但是当我在repl中用
:t String->List type
检查解析器返回的类型时,我得到了
type
,看起来它应该可以工作


如果有人能很好地解释此数据声明不起作用的原因,或者为表示解析器数据类型提供更好的替代方案,我将不胜感激。

在定义数据类型解析器时,第一行是说此类型接受类型并返回类型,在本例中,它接受
a
并返回
解析器a

因此,构造函数应该返回
解析器a

类似于
列表
,它接受
a
并返回
列表a

您当前在构造函数中返回的不是类型
Parser
——因为单词
Parser
不会出现在右边

除此之外,我不确定你如何最好地表达这一点。 但是,有些解析器库已经用Idris编写,看看这些可能会有所帮助吗?例如,看看这个库列表,首先提到的是解析器:- 在哈斯克尔

type Parser a = String -> [(a,String)]
不会创建新类型,它只是一个类型同义词。您可以在Idris中执行与以下类似的操作

Parser : Type -> Type
Parser a = String -> List (a, String)
然后将助手定义定义为返回
Parser a
s的简单函数:

fail : Parser a
fail = const []

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

谢谢,这正是我想要的。您能否解释或指出类型签名中没有的
->
资源?我不知道箭头可以在类型声明之外使用。
=>
只是lambdas的Idris语法:Haskell中的
\x->e
在Idris中写为
\x=>e
。对不起,应该更清楚一些。我指的是行
解析器a=String->List(a,String)
。这行中的
->
基本上是在创建一个函数类型吗?无论它出现在类型签名还是函数定义中,
->
是否意味着相同的事情?这与Haskell中的
类型解析器a=String->LIst(a,String)
完全相同:它没有定义新的类型,它只引入了一个类型同义词。棘手的部分是,
解析器
是一个函数,它将一个
类型
作为参数,并返回另一个
类型
。它就像Haskell中的类型构造函数
*->*
;但在Idris中,它不需要以任何不同的方式定义,就像一个函数,它接受一个
Int
类型的参数并返回一个
Bool