.Net 常量的 F# 模式匹配

发布于 2024-09-30 15:49:58 字数 362 浏览 3 评论 0原文

下一个示例中的代码

open System.Drawing

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

无法编译。错误为错误 1 ​​未定义字段、构造函数或成员“Black”

如何针对以大写字母开头的 .Net 常量或枚举进行模式匹配?

就其价值而言,编译器是“Microsoft (R) F# 2.0 Interactive build 4.0.30319.1”。

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".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

终难愈 2024-10-07 15:49:58

扩展 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"

或者,如果您同样只处理黑色和白色,但您总是希望黑色计算为 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"

更一般地,您甚至可以模拟 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"

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"
べ映画 2024-10-07 15:49:58

您不能对任意对象值进行模式匹配。使用 if then elsewhen 条件:

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

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"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文