f# - 为什么事件模式以这种方式表现?

标签 f# active-pattern

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

作者承认这是

“如果你还记得值的 let 绑定(bind)是基于模式匹配的数据反汇编的极端情况,那么这个有点令人难以置信的例子就会变得清晰,所以 I'm active pattern 被应用于输入参数 40 并将结果 42 绑定(bind)到 x。”

我不明白。为什么 I'm active pattern 被应用到 40,因为 40 在右边?直觉上我会猜测 y = 38,而不是 42,将表达式 let (`` I'm active pattern `` y) = 40 看成一个隐式函数。

谁能解释一下?

最佳答案

这就是事件模式的特别之处;对于普通函数,let f x = ... 的定义反射(reflect)了 f 的应用:您可以通过代入 e 在心理上评估 f e 用于定义中的 x

相比之下,使用事件模式 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"

关于f# - 为什么事件模式以这种方式表现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42142749/

相关文章:

f# - 在 F# 中适当使用事件模式

f# - 在 F# 中实现索引器

f# - 联盟成员的子集在模式匹配中为 "parameter"

f# - 重用 F# 事件模式结果

f# - 了解 F# 值限制错误

f# - 如何将复杂的表达式传递给参数化的事件模式?

list - F# 对列表中的所有整数求和

F# 尾递归,为什么不写一个 while 循环?

list - 在 F# 中,map2 如何处理不均匀的列表长度?