Для следующих типов:
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
При написании функции, которая проверяет, принадлежит ли первый токен в списке к определенному типу токена, например:
let token (tok: Token) : Parser<Token> = Parser <| fun lst ->
match lst with
| [] -> None, lst
| t::ts -> if t = tok then Some t, ts else None, lst
Есть ли способ обобщить это так, чтобы параметр tok
мог просто быть любым из конструкторов из Token
, то есть ADD
или INT
, и без параметров, данных этим конструкторам?
Таким образом, функция token
может быть запущена как run (token ADD) ts
вместо run (token (ADD (Pos 1 1))) ts
.
То, что я пробовал до сих пор, - это использовать GetType()
через который я могу получить имя конструктора в виде строки для текущего токена t
, проверяемого следующим образом:
t.GetType().Name // Output: "INT" or "ADD" as strings
Однако, если я просто передаю конструктор INT
в качестве параметра tok
в token
, tok.GetType().Name
не приводит к "INT"
, так как конструктор INT
имеет тип Pos * int -> Token
...
Возможно, чтобы реализовать вышеприведенную идею, основанную на GetType()
, решение могло бы быть, чтобы найти способ преобразовать INT
или ADD
в строки "INT"
или "ADD"
соответственно.