Here is my problem: I am trying to write a parser using the power of active templates in F #. The main signature of the parsing function is as follows:
LazyList<Token> -> 'a * LazyList<Token>
The value of this requires a lazy list of tokens and returns the result of the analysis and a new list of tokens after parsing in order to follow the functional design.
Now, as a next step, I can define active patterns that will help me match some constructs directly in expression expressions, this way
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
and then match the parsing results in this way to a high level
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
The problem with this code is that each new mapped construct is nested, which is impossible to read, especially if you have a long chain of results to match. I would like to be able to define an appropriate operator, such as the :: operator for a list, which would allow me to do the following:
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
But I do not think that such a thing is possible in F #. I would even agree with a design in which I need to call a specific active ChainN template, where N is the number of elements that I want to parse, but I donβt know how to create such a function, if possible.
Any tips or guidance on this? Is there an obvious design that I have not seen?