Using a variable in pattern matching in Ocaml or F#
binding, f#, ocaml, pattern-matching, variables
Solution
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 `value` is zero and otherwise succeeds and returns the addition of the value and the specified parameter:
let (|Test|_|) arg value =
if value = 0 then None else Some(value + arg)
You can specify the parameter in pattern matching like this:
match 1 with
| Test 100 res -> res // 'res' will be 101
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 symbol `res`):
let (|Equals|_|) arg x =
if (arg = x) then Some() else None
let foo x y =
match x with
| Equals y -> "equal"
| _ -> "not equal"
You can use this as a nested pattern, so you should be able to rewrite your example using the `Equals` active pattern.
Problem
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?