Parsing 提取并比较有区别的联合构造函数
鉴于以下类型:Parsing 提取并比较有区别的联合构造函数,parsing,functional-programming,f#,parser-combinators,discriminated-union,Parsing,Functional Programming,F#,Parser Combinators,Discriminated Union,鉴于以下类型: type Pos = {line:int; col:int} let Pos line col = {line = line; col = col} type Token = | ADD of Pos | INT of Pos * int let ts = [INT (Pos 1 1, 4);ADD (Pos 1 2);INT (Pos 1 3, 7)] type Parser<'a> = Parser of (Token list ->
type Pos = {line:int; col:int}
let Pos line col = {line = line; col = col}
type Token =
| ADD of Pos
| INT of Pos * int
let ts = [INT (Pos 1 1, 4);ADD (Pos 1 2);INT (Pos 1 3, 7)]
type Parser<'a> = Parser of (Token list -> 'a option * Token list)
let run p ts = let (Parser pfun) = p in pfun ts
但是,如果我只是将构造函数INT
作为tok
参数传递给token
,tok.GetType().Name
不会产生“INT”
,因为构造函数INT
的类型是Pos*INT->token
可能要使上述基于
GetType()
的想法发挥作用,一个解决方案是找到一种方法,将INT
或ADD
分别转换为字符串“INT”
或“ADD”
。我可能不理解
您可以定义并传递匹配器
let matchAdd = function
| ADD p as t -> Some t
| _ -> None
let matchInt = function
| INT _ as t -> Some t
| _ -> None
let token2 matcher : Parser<Token> = Parser <| fun lst ->
match lst with
| [] -> None, lst
| t::ts ->
match (matcher t) with
| Some t -> Some t, ts
| None -> None, lst
让matchAdd=函数
|将p添加为t->Some t
|无
设matchInt=函数
|INT uu作为t->Some t
|无
让token2匹配器:Parser=Parser
匹配lst与
|[]->无,lst
|t::ts->
匹配(匹配器t)与
|一些t->一些t,ts
|无->无,lst
?您能传递“匹配”语句而不是“令牌”吗?然后定义一个匹配每个令牌类型的函数。实际上有大量的
token
cases/constructor,所以我试图找到一种方法来概括它,而不必为每个token
constructor手动编写函数或匹配case。每个令牌都可以有一个类型,然后将其嵌入到数据构造函数中,然后传入令牌的类型,这将是类型安全的,并且没有令人讨厌的反射,但这仍然是一种成本…您也可以使用无标记编码…这基本上有点像访客/工厂…但我想您最终会得到我上面发布的东西
t.GetType().Name // Output: "INT" or "ADD" as strings
let matchAdd = function
| ADD p as t -> Some t
| _ -> None
let matchInt = function
| INT _ as t -> Some t
| _ -> None
let token2 matcher : Parser<Token> = Parser <| fun lst ->
match lst with
| [] -> None, lst
| t::ts ->
match (matcher t) with
| Some t -> Some t, ts
| None -> None, lst