为什么活动模式以这种方式表现?

Why active patterns behave this way?

我在 Gene Belitski 的优秀著作 F# Design Patterns 中找到了这段代码:

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
*)

作者认得这是

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

我不明白。鉴于 40 在右侧,为什么 I'm active pattern 应用于 40?直觉上我会猜测 y = 38,而不是 42,将表达式 let (`` I'm active pattern `` y) = 40 视为隐式函数。

谁能解释一下?

这就是活动模式的特别之处;对于普通函数,定义 let f x = ... 反映了 f 的应用:您可以通过在定义中用 e 代替 x 来在心理上评估 f e

相比之下,使用活动模式 let (|P|) x = ...,当您看到 let (P y) = e 时,新标识符 y 将获得将定义主体应用于 e 的结果].

对于结果类型与输入类型不同的活动模式,这可能更容易看到:

let (|StringValue|) (i:int) = sprintf "%i" i

let (StringValue s) = 1 // s is of type string, with value "1"