Is a when guard the only way to identify if items in a tuple are the same value in a pattern match? [duplicate]

StackOverflow https://stackoverflow.com/questions/19051226

  •  29-06-2022
  •  | 
  •  

Consider the following function:

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

What I'd like to do is replace | (alpha, red, green, blue) when red = blue && red = green && red <> 255uy -> with | (alpha, value, value, value) when value <> 255uy ->. If I do that though, I get a 'value' is bound twice in this pattern error.

Is there a way to rewrite the line to simplify the guard that satisfies the compiler?

有帮助吗?

解决方案

This is where F#'s active patterns are useful -- it lets you put the matching logic into a function, then you can use the patterns without having to worry about how the matching is happening behind the scenes.

For example, you could define an active pattern for your code and use it like this:

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top