.Net常量的F#模式匹配

Muh*_*uri 3 f# pattern-matching

下一个例子中的代码,

open System.Drawing

let testColor c =
    match c with
    | Color.Black -> 1
    | Color.White -> 0
    | _ -> failwith "unexpected color"
Run Code Online (Sandbox Code Playgroud)

不编译.错误是Error 1 The field, constructor or member 'Black' is not defined.

如何模拟以大写字母开头的.Net常量或枚举的匹配?

对于它的价值,编译器是"Microsoft(R)F#2.0 Interactive build 4.0.30319.1".

Ste*_*sen 11

根据Brian的回答,模式匹配与switch语句不同.它们测试和分解输入的结构而不是测试对象的相等性.但是如果在整个程序中经常使用分为黑色,白色和其他颜色的颜色,则可以选择活动模式.对于一次性"锅炉板"成本,它们允许您围绕要操纵的对象定义结构.例如,

open System.Drawing
let (|Black|White|Other|) (color:Color) =
    if color = Color.Black then Black
    elif color = Color.White then White
    else Other

let testColor c =
    match c with
    | Black -> 1
    | White -> 0
    | Other -> failwith "unexpected color"
Run Code Online (Sandbox Code Playgroud)

或者,如果您同样只处理黑白,但您总是希望Black评估为1而白色评估为0,那么您可以使用部分活动模式:

let (|KnownColor|_|) (color:Color) =
    if color = Color.Black then Some(1)
    elif color = Color.White then Some(0)
    else None

let testColor2 c =
    match c with
    | KnownColor i -> i
    | _ -> failwith "unexpected color"
Run Code Online (Sandbox Code Playgroud)

更一般地,您甚至可以使用通用的部分活动模式模拟switch语句:

let (|Equals|_|) (lhs) (rhs)  =
    if lhs = rhs then Some(lhs) else None

let testColor3 c =
    match c with
    | Equals Color.Black _ -> 1
    | Equals Color.White _ -> 0
    | _ -> failwith "unexpected color"

let testString c =
    match c with
    | Equals "Hi" _ -> 1
    | Equals "Bye" _ -> 0
    | _ -> failwith "unexpected string"
Run Code Online (Sandbox Code Playgroud)


Bri*_*ian 6

您无法对任意对象值进行模式匹配.使用if then elsewhen条件:

let testColor c = 
    match c with 
    | c when c = Color.Black -> 1 
    | c when c = Color.White -> 0 
    | _ -> failwith "unexpected color"
Run Code Online (Sandbox Code Playgroud)