gpt4 book ai didi

F#:事件模式的高级使用

转载 作者:行者123 更新时间:2023-12-04 12:41:10 26 4
gpt4 key购买 nike

这是我的问题:我正在尝试编写一个解析器,利用 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 是我想要解析的元素数,但如果可能的话,我不知道如何设计这样的功能。

对此有何建议或指示?是否有我没有看到的明显设计?

最佳答案

我也有类似的想法,但实际上放弃了这种精确的设计。您可以做的是使用实际列表。

在这种情况下,您将拥有一个 CombinedList,它由(首先)一个充当缓冲区的普通列表和(其次)一个惰性列表组成。

当你想匹配一个模式时,你可以这样做:

match tokens.EnsureBuffer(4) with
| el1 :: el2 :: remaining -> (el1.v+el2.v, tokens.SetBuffer(remaining))
| el3 :: el4 :: el5 :: el6 :: remaining -> (el1.v-el2.v+el3.v-el4.v, tokens.SetBuffer(remaining))

其中,EnsureBuffer 和 SetBuffer 可以改变“ token ”并返回它,或者如果不需要更改则返回它,否则返回一个新实例。

那能解决你的问题吗?
弗朗索瓦

关于F#:事件模式的高级使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23628985/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com