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