.net 对活动模式感到困惑

.net 对活动模式感到困惑,.net,f#,functional-programming,.net,F#,Functional Programming,我了解如何在F#中定义和使用活动模式,包括部分活动模式,以及可用的不同类型的模式。例如 let (|Big|Small|) animal = if animal.IsBig then Big(animal) else Small(animal) let f = function | Big(_) -> "big" |Small(_) -> "small 然而,对于在let绑定、参数和其他地方使用活动模式和有区别的联合,我感到困惑。例如,MSDN具有以下代码: let GetSubs

我了解如何在F#中定义和使用活动模式,包括部分活动模式,以及可用的不同类型的模式。例如

let (|Big|Small|) animal = if animal.IsBig then Big(animal) else Small(animal)
let f = function | Big(_) -> "big" |Small(_) -> "small
然而,对于在
let
绑定、参数和其他地方使用活动模式和有区别的联合,我感到困惑。例如,MSDN具有以下代码:

let GetSubstring1 (Slice(p0, p1, text)) = 
    printfn "Data begins at %d and ends at %d in string %s" p0 p1 text
    text.[p0..p1]
这让我有点困惑

具体问题。比如说我有一个受歧视的工会

type Union = A of int * int | B of int
我是否可以制作一个只接受联合的函数

let f (A(a, b)) = a + b

在这种情况下,它告诉我存在不匹配的模式。有办法满足它吗?

正如@ildjarn所指出的,这适用于所有模式。它们可以出现在
match
子句中(和类似的
函数中),也可以出现在
let
绑定函数的参数声明中,甚至出现在
let
值绑定中

关键区别在于,使用
let
,您只希望使用始终成功的完整模式。对于
匹配
函数
,这是不需要的,因为存在多个子句,因此如果第一个子句失败,则可以继续匹配并尝试下一个子句

例如,以下完整模式接受
int
,并将其作为
字符串返回:

let (|AsString|) (n:int) = n.ToString()
以下是一些使用方法:

let (AsString s) = 42         // Defines a value 's' of type string
match 3 with AsString s -> s  // Returns a value "3" of type string
let convert (AsString s) = s  // Defines a function 'int -> string'
let convert = function AsString s -> s  // Same as the previous line
编辑:为了回答第二个问题,如果您将
let
与不完整的模式一起使用(即,仅接受一个区分的联合案例),则会收到编译器警告,代码可能在运行时失败(如果您将其与另一个区分的联合案例一起调用):

如果您需要定义一个只适用于其中一种情况的函数,那么您需要定义一个单独的类型

type AInfo = int * int 
type Union = A of AInfo | B of int  

然后,您可以编写一个只接受
AInfo
的函数(但在这两个选项都表示有效输入的地方,您仍然可以使用
Union

这个问题比活动模式更为普遍–所有模式匹配可能发生在许多明显的上下文中。
type AInfo = int * int 
type Union = A of AInfo | B of int