I found this code in the excellent book F# Design Patterns
by Gene Belitski:
let (| `` I'm active pattern `` |) x = x + 2
let (`` I'm active pattern `` y) = 40
(*
val ( |`` I'm active pattern ``| ) : x:int -> int
val y : int = 42
*)
The author recognizes that this is
"a slightly mind boggling example that becomes clear if you remember that the let binding of a value is a corner case of pattern matching based data disassembling, so I'm active pattern
gets applied to input argument 40 and binds the result 42 to x."
I don't get it. Why does I'm active pattern
gets applied to 40, given that 40 is on the right-hand side? Intuitively I would guess that y = 38, not 42, looking at the expression let (`` I'm active pattern `` y) = 40
as an implicit function.
Can anyone explain?
That's what makes active patterns special; with a normal function the definition let f x = ...
mirrors the application of f
: you can mentally evaluate f e
by substituting e
for x
in the definition.
By contrast, with an active pattern let (|P|) x = ...
, when you see let (P y) = e
the fresh identifier y
will get the result of applying the body of the definition to e
.
This is perhaps easier to see with an active pattern where the result type differs from the input type:
let (|StringValue|) (i:int) = sprintf "%i" i
let (StringValue s) = 1 // s is of type string, with value "1"