Соответствие шаблону F # констант .Net - PullRequest
2 голосов
/ 07 ноября 2010

Код в следующем примере,

open System.Drawing

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

не компилируется. Ошибка Error 1 The field, constructor or member 'Black' is not defined.

Как мне сопоставить шаблон с константами или перечислениями .Net, которые начинаются с заглавных букв?

Для чего это стоит, компилятор "Microsoft (R) F # 2.0 Интерактивная сборка 4.0.30319.1".

Ответы [ 2 ]

11 голосов
/ 07 ноября 2010

Расширяя ответ Брайана, сопоставление с образцом - это не зверь, а операторы switch. Они проверяют и разлагают структуру входных данных, а не проверяют равенство объектов. Но Active Patterns может быть вариантом, если разделение цветов на черный, белый и другой будет часто использоваться в вашей программе. За единовременную стоимость «котельной плиты» они позволяют вам определить структуру вокруг объекта, которым вы манипулируете. Например,

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, используя общий 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"
5 голосов
/ 07 ноября 2010

Вы не можете сопоставить шаблон с произвольными значениями объекта. Используйте условия if then else или when:

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