I have a function of the form
'a -> ('a * int) list -> int
let rec getValue identifier bindings =
match bindings with
| (identifier, value)::tail -> value
| (_, _)::tail -> getValue identifier tail
| [] -> -1
I can tell that identifier is not being bound the way I would like it to and is acting as a new variable within the match expression. How to I get identifier to be what is passed into the function?
Ok! I fixed it with a pattern guard, i.e. | (i, value)::tail when i = indentifier -> value
but I find this ugly compared to the way I originally wanted to do it (I’m only using these languages because they are pretty…). Any thoughts?
You can use F# active patterns to create a pattern that will do exactly what you need. F# supports parameterized active patterns that take the value that you’re matching, but also take an additional parameter.
Here is a pretty stupid example that fails when the
valueis zero and otherwise succeeds and returns the addition of the value and the specified parameter:You can specify the parameter in pattern matching like this:
Now, we can easily define an active pattern that will compare the matched value with the input argument of the active pattern. The active pattern returns
unit option, which means that it doesn’t bind any new value (in the example above, it returned some value that we assigned to a symbolres):You can use this as a nested pattern, so you should be able to rewrite your example using the
Equalsactive pattern.