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 Tree
或 Parser Char
或 Parser 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 的这个特殊定义要么是零解析的空列表,表示不可能进行解析,要么是恰好一个解析的单例列表,表示解析成功。)
我对 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 Tree
或 Parser Char
或 Parser 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 的这个特殊定义要么是零解析的空列表,表示不可能进行解析,要么是恰好一个解析的单例列表,表示解析成功。)