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