F#:活动模式的高级使用

F#:活动模式的高级使用,f#,pattern-matching,F#,Pattern Matching,我的问题是:我正试图利用F#中活动模式的功能编写一个解析器。解析函数的基本特征如下 LazyList<Token> -> 'a * LazyList<Token> 然后以这种方式以高级方式匹配解析结果 let parse_subprogram_profile = function | Tok (Kw (KwProcedure | KwFunction), QualName(qual_name,

我的问题是:我正试图利用F#中活动模式的功能编写一个解析器。解析函数的基本特征如下

LazyList<Token> -> 'a * LazyList<Token>
然后以这种方式以高级方式匹配解析结果

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
我在这段代码中遇到的问题是,每一个新匹配的构造都是嵌套的,这是不可读的,特别是当您要匹配一长串结果时。我希望能够定义一个匹配的运算符,例如list的::运算符,这将使我能够执行以下操作:

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是我想要解析的元素数,但如果可能的话,我不知道如何设计这样一个函数


对此有什么建议或指示吗?有一个明显的设计我没有看到吗?

我也有这样的想法,但实际上放弃了这个确切的设计。您可以使用实际列表

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

如果要与模式匹配,可以执行以下操作:

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))
其中,Rebuffer和SetBuffer可以变异“令牌”并返回它,或者在不需要更改的情况下返回它,或者在其他情况下返回新实例

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

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))