Является ли блокировка when единственным способом определить, являются ли элементы в кортеже одним и тем же значением в соответствии с шаблоном?

Рассмотрим следующую функцию:

let private actionPixel(pixelColour:Color) =
    match (pixelColour.A, pixelColour.R, pixelColour.G, pixelColour.B) with
        | (0uy, _, _, _) -> transparent
        | (alpha, red, green, blue) when red = blue && red = green && red <> 255uy ->
            Color.FromArgb(calculateAlpha (int alpha) (int red), 0, 0, 0)
        | _ -> pixelColour

Я бы хотел заменить | (alpha, red, green, blue) when red = blue && red = green && red <> 255uy -> на | (alpha, value, value, value) when value <> 255uy ->. Если я это сделаю, я получу ошибку 'value' is bound twice in this pattern.

Есть ли способ переписать строку, чтобы упростить защиту, удовлетворяющую компилятору?


person David Arno    schedule 27.09.2013    source источник
comment
Тесно связано: stackoverflow .com/questions/14561325/   -  person Mark Pattison    schedule 27.09.2013
comment
Это похоже на дублированный вопрос. Должен ли я просто удалить его или он должен быть закрыт голосованием?   -  person David Arno    schedule 27.09.2013


Ответы (1)


Именно здесь полезны активные шаблоны F# — они позволяют поместить логику сопоставления в функцию, после чего вы можете использовать шаблоны, не беспокоясь о том, как сопоставление происходит за кулисами.

Например, вы можете определить активный шаблон для своего кода и использовать его следующим образом:

open System.Drawing

let (|Transparent|Grayscale|Color|) (color : Color) =
    if color.A = 0uy then Transparent
    elif color.R = color.G && color.R = color.B && color.R <> 255uy then
        let newAlpha = calculateAlpha (int alpha) (int red)
        Grayscale (Color.FromArgb (newAlpha, 0, 0, 0))
    else
        Color color

let private actionPixel (pixelColour : Color) =
    match pixelColour with
    | Transparent ->
        Color.Transparent
    | Grayscale c ->
        c
    | Color c ->
        c
person Jack P.    schedule 27.09.2013
comment
Я не уверен, что мне это нравится, но это явно правильный ответ на мой вопрос. Так принято. - person David Arno; 27.09.2013