Haskell 正在用 parsec 解析

Haskell parsing with parsec

我对 Haskell 编程还很陌生。我目前正在尝试熟悉一些使用 parsec 进行解析的源代码。

有两件事让我印象深刻:

type Parser = String -> Tree

按照作者的说法,这应该是一个函数的声明?这实际上应该是这样的:

Parser :: String -> Tree right?

另一个歧义在下面的代码中:

item :: Parser Char
item = P (\inp -> case inp of......

根据我的理解,这是函数的类型声明,对吗?

这不应该是

item :: Parser -> Char

谢谢你帮助我

问候克里斯托夫

type Parser = String -> Tree

According to the author, this is supposed to be a declaration of a function? That should actually look like this:

更准确地说,Parser 是类型 String -> Tree 的类型别名,它是一个接受 String 和 returns 和 Tree 的函数。

所以Parser是一个新的类型名称。

另一方面,比较一下

Parser :: String -> Tree

这声明了一个名称为 Parser 且类型为 String -> Tree 的函数。因此,在第一种情况下,我们声明一个新类型,在第二种情况下,我们声明一个具有特定类型的名称。

如评论中所说,这应该是

parser :: String -> Tree

因为函数名称应以小写字母开头,而类型名称应以大写字母开头。

我假设您正在查看 this slide deck。作者实际说的是:

In a functional language such as Haskell, parsers can naturally be viewed as functions.

-- A parser is a function that takes a string 
-- and returns some form of a tree
type Parser = String -> Tree

作者的意思是解析器是函数,这样的解析器函数的类型可能是作者定义的Parser类型作为类型 String -> Tree.

的类型别名

也就是说,在定义类型别名后 Parser 使用:

type Parser = String -> Tree

实际的解析器可以声明为类型 Parser(等同于类型 String -> Tree),如下所示:

-- here is a very bad parser capable of parsing only one possible program
myTreeParser :: Parser
myTreeParser "2*3+4" = Plus (Times (Num 2) (Num 3)) (Num 4)
myTreeParser _ = error "Parser only supports the program '2*3+4'"

考虑类似的语​​句:“在支持代数数据类型的语言中,例如 Haskell,点自然可以表示为成对的浮点数:type Point = (Double, Double)。其目的不是定义这样一个点,而是通过类型别名 Point 来描述点的类型,该别名被定义为等同于浮点数对的类型 (Double, Double)

作者继续完善 Parser 类型,指出 (1) 解析器可能不会使用其所有输入,因此应该 return (Tree, String) 而不仅仅是 Tree, (2) 他们可能能够以多种方式解析他们的输入(最重要的是“零”方式,如果无法解析输入),因此应该 return 可能的解析结果列表 [(Tree, String)],并且 (3) 可能需要解析除 Tree 之外的其他内容,因此应该将输入泛化为将输入解析为任意类型:

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

这定义了一个类型别名Parser,即参数化,意味着Parser本身不是一个完整的类型,而是Parser TreeParser CharParser Double 是一个完整类型,表示一个解析器解析一个 Tree, Char, 或 Double.

所以声明:

item :: Parser Char

写的是正确的。使用此 Parser 类型别名的最终版本:

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

类型Parser Char等同于类型:

String -> [(Char, String)]

也就是说,item 的类型是接受输入 String 并尝试解析输入的开头以生成 Char 值的解析器的类型,加上String 的剩余部分在被解析的部分之后。最终,它 return 零个或多个这样的可能解析。 (item return 的这个特殊定义要么是零解析的空列表,表示不可能进行解析,要么是恰好一个解析的单例列表,表示解析成功。)