【发布时间】:2014-05-13 10:40:32
【问题描述】:
这是我的问题:我正在尝试编写一个解析器,利用 F# 中活动模式的强大功能。解析函数的基本签名如下
LazyList<Token> -> 'a * LazyList<Token>
意思是取一个惰性token列表,返回解析结果和解析后的新token列表,遵循函数式设计。
现在,作为下一步,我可以定义活动模式,这将帮助我直接在匹配表达式中匹配一些结构,因此
let inline (|QualName|_|) token_stream =
match parse_qualified_name token_stream with
| Some id_list, new_stream -> Some (id_list, new_stream)
| None, new_stream -> None
let inline (|Tok|_|) token_stream =
match token_stream with
| Cons (token, tail) -> Some(token.variant, tail)
| _ -> None
然后以这种方式以高级方式匹配解析结果
let parse_subprogram_profile = function
| Tok (Kw (KwProcedure | KwFunction),
QualName(qual_name,
Tok (Punc (OpeningPar), stream_tail))) as token_stream ->
// some code
| token_stream -> None, token_stream
我对这段代码的问题是每个新的匹配结构都是嵌套的,这是不可读的,特别是如果你有很长的结果链要匹配。我希望能够定义匹配的运算符,例如列表的 :: 运算符,这将使我能够执行以下操作:
let parse_subprogram_profile = function
| Tok (Kw (KwProcedure | KwFunction)) ::
QualName(qual_name) ::
Tok (Punc (OpeningPar)) :: stream_tail as token_stream ->
// some code
| token_stream -> None, token_stream
但我认为这样的事情在 F# 中是不可能的。我什至会接受一种设计,其中我必须调用特定的“ChainN”活动模式,其中 N 是我要解析的元素数,但如果可能的话,我不知道如何设计这样的功能。
对此有何建议或指示?有没有我没看到的明显设计?
【问题讨论】:
标签: f# pattern-matching