Active pattern

Active patterns
Description: Active pattern can save mulitple matches. This sample shows how to avoid use nested match statement.
let ActivePatternSample() = 
let (|Match|) v i = (v, i)
let tag, num = true, 1
let r = match tag, num with
| true, (Match "ID0" (str, 0) | Match "ID1" (str, 1)) -> sprintf "%s" str
| _ -> "unknown"
printfn "%s" r
Assert.AreEqual(r, "ID0")

Execution Result:
failwith not equal

Partial patterns

Active patterns
Description: Need to partition only part of the input space. In that case, you write a set of partial patterns each of which match some inputs but fail to match other inputs. Active patterns that do not always produce a value are called partial active patterns; they have a return value that is an option type. To define a partial active pattern, you use a wildcard character (_) at the end of the list of patterns inside the banana clips. The following code illustrates the use of a partial active pattern.
let ActivePatternSample1() = 
let (|Integer|_|) (str: string) =
let mutable intvalue = 0
if System.Int32.TryParse(str, &intvalue) then Some(intvalue)
else None
let (|Float|_|) (str: string) =
let mutable floatvalue = 0.0
if System.Double.TryParse(str, &floatvalue) then Some(floatvalue)
else None
let parseNumeric str =
match str with
| Integer i -> printfn "%d : Integer" i
| Float f -> printfn "%f : Floating point" f
| _ -> printfn "%s : Not matched." str
parseNumeric "1.1"
parseNumeric "0"
parseNumeric "0.0"
parseNumeric "10"
parseNumeric "Something else"

Execution Result:
1.100000 : Floating point
0 : Integer
0.000000 : Floating point
10 : Integer
Something else : Not matched.

Active pattern with arguments

Active patterns
Description: Active pattern determines the input value format by using an active pattern with arguments.
let ActivePatternSample2() = 
let ( |Bool|Int|Float|String| ) input =
let sucess, res = Boolean.TryParse input
if sucess then Bool(res)
let sucess, res = Int32.TryParse input
if sucess then Int(res)
let sucess, res = Double.TryParse input
if sucess then Float(res)
else String(input)
let printInputWithType input =
match input with
| Bool b -> printfn "Boolean: %b" b
| Int i -> printfn "Integer: %i" i
| Float f -> printfn "Floating point: %f" f
| String s -> printfn "String: %s" s
printInputWithType "true"
printInputWithType "12"
printInputWithType "-12.1"

Execution Result:
Boolean: true
Integer: 12
Floating point: -12.100000

Active pattern: NULL

Active patterns
Description: Active pattern determines if the input value is null. When sample is executed under debug mode, it throws exception which is expected behavior.
let ActivePatternSample3() =     
let inline isNull v = System.Object.ReferenceEquals(v, null)
let (|Null|_|) value = if isNull value then Some() else None
let check v =
match v with
| Null -> nullArg "v is null"
| _ -> ()
check null

Execution Result:
Exception raised: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: v is null
at Microsoft.FSharp.Core.Operators.Raise[T](Exception exn)
at Samples.Others.check@482-1T.Invoke(a v) in C:\MyCode\Samples\SampleProject\SampleProject\Samples.Others.fs:line 484
at Samples.Others.ActivePatternSample3() in C:\MyCode\Samples\SampleProject\SampleProject\Samples.Others.fs:line 486
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Support.Helper.Utils.samples@190-3.Invoke(Unit unitVar0) in C:\MyCode\Samples\SampleProject\SampleProject\Supportive.Helper.fs:line 190
at Support.Helper.Utils.getExecutionResult(FSharpOption`1 sampleOption) in C:\MyCode\Samples\SampleProject\SampleProject\Supportive.Helper.fs:line 256

Last edited Sep 12, 2011 at 11:14 PM by ttliu2000, version 3


No comments yet.