F# pattern matching of .Net constants

徘徊边缘 提交于 2019-12-07 15:08:41

问题


The code in the next example,

open System.Drawing

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

doesn't compile. The error is Error 1 The field, constructor or member 'Black' is not defined.

How do I pattern match against .Net constants or enums that start with capital letters?

For what it's worth, the compiler is "Microsoft (R) F# 2.0 Interactive build 4.0.30319.1".


回答1:


You can't pattern-match against arbitrary object values. Use an if then else or when conditions:

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



回答2:


Expanding upon Brian's answer, pattern-matches are a different beast than switch statements. They test and decompose the structure of an input rather than test object equality. But Active Patterns may be an option if the division of colors into Black, White and Other will be used often throughout your program. For a one-time "boiler-plate" cost, they let you define a structure around the object you are manipulating. For example,

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"

Or, if you are likewise dealing with only Black and White, but you always want Black to evaluate as 1 and White to evaluate as 0, then you can use Partial Active Patterns:

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"

More generally, you can even emulate a switch statement using a generic Partial Active Pattern:

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"


来源:https://stackoverflow.com/questions/4117667/f-pattern-matching-of-net-constants

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!