.net 对活动模式感到困惑
我了解如何在F#中定义和使用活动模式,包括部分活动模式,以及可用的不同类型的模式。例如.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
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