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
  •  | 
  •  

Question

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?

Was it helpful?

Solution

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top