I'm new to F# and not quite familiar with the whole pattern matching idea. I tried to search for a better solution to my problem but I fear I can't even express the problem properly – I hope the question title is at least somewhat accurate.
What I want to do is extract 2 "parameters" from listMethod
.
listMethod
is of one of several types that have a string and an Expression
"parameter" (I suspect parameter is the wrong term):
let (varDecl, listExpr) =
match listMethod with
| Select (var, expr) -> (var, expr)
| Where (var, expr) -> (var, expr)
| Sum (var, expr) -> (var, expr)
| Concat (var, expr) -> (var, expr)
Then I continue to work with varDecl
and at the end have a similar match expression with the actual listMethod code that makes use of several temporary variables I created based on varDecl
.
My question now is: How can I make the above code more compact?
I want to match all those types that have 2 parameters (of type string
and Expression
) without listing them all myself, which is kinda ugly and hard to maintain.
The ListMethod
type is declared as follows (the whole thing is a FsLex/FsYacc project):
type ListMethod =
| Select of string * Expr
| Where of string * Expr
| Sum of string * Expr
| Concat of string * Expr
| ...
| somethingElse of Expr
(as of now I only have types of the form string * Expr
, but that will change).
I reckon that this is a fairly dumb question for anyone with some experience, but as I've said I'm new to F# and couldn't find a solution myself.
Thanks in advance!
Edit: I'd really like to avoid listing all possible types of listMethod
twice. If there's no way I can use wildcards or placeholders in the match
expressions, perhaps I can modify the listMethod
type to make things cleaner.
One option that comes to mind would be creating only 1 type of listMethod
and to create a third parameter for the concrete type (Select, Where, Sum).
Or is there a better approach?
This is probably the standard way:
let (varDecl, listExpr) =
match listMethod with
| Select (var, expr)
| Where (var, expr)
| Sum (var, expr)
| Concat (var, expr) -> (var, expr)
The |
sign means or
, so if one of these match, the result will be returned. Just make sure that every case has exactly the same names (and types).
As Chuck commented, this is an even better solution:
let (Select (varDecl, expr)
| Where (varDecl, expr)
| Sum (varDecl, expr)
| Concat (varDecl, expr)) = listMethod