Active Patterns can be used to make calling some .NET API's feel more natural, particularly those that use an output parameter to return more than just the function return value.
For example, you'd normally call the System.Int32.TryParse
method as follows:
let couldParse, parsedInt = System.Int32.TryParse("1")
if couldParse then printfn "Successfully parsed int: %i" parsedInt
else printfn "Could not parse int"
You can improve this a bit using pattern matching:
match System.Int32.TryParse("1") with
| (true, parsedInt) -> printfn "Successfully parsed int: %i" parsedInt
| (false, _) -> printfn "Could not parse int"
However, we can also define the following Active Pattern that wraps the System.Int32.TryParse
function:
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| (true, parsedInt) -> Some parsedInt
| _ -> None
Now we can do the following:
match "1" with
| Int parsedInt -> printfn "Successfully parsed int: %i" parsedInt
| _ -> printfn "Could not parse int"
Another good candidate for being wrapped in an Active Patterns are the regular expressions API's:
let (|MatchRegex|_|) pattern input =
let m = System.Text.RegularExpressions.Regex.Match(input, pattern)
if m.Success then Some m.Groups.[1].Value
else None
match "bad" with
| MatchRegex "(good|great)" mood ->
printfn "Wow, it's a %s day!" mood
| MatchRegex "(bad|terrible)" mood ->
printfn "Unfortunately, it's a %s day." mood
| _ ->
printfn "Just a normal day"