Search code examples
f#functional-programmingpattern-matchingactive-pattern

How to pattern-match when something is NOT of a particular type


We're all used to pattern-matching for cases when something is a particular type, e.g.,

match x with
| Y(x) :: tail -> ... // assumes List.head(x) is of type Y(x)

But how can can I match the case when something is not of a particular type? E.g.,

match x with
| Not Y(_) :: tail -> ... // List.head(x) is definitely not a Y

Thanks!


Solution

  • While there is no direct support for Not you can use a partial active pattern.

    type Color = | Red | Green | Blue
    
    let (|NotRed|_|) = function
        | Red -> None
        | color -> Some color
    
    let rec print = function
        | (NotRed head) :: tail -> 
            printfn "%A is Not Red" head
            print tail
        | _ :: tail -> print tail
        | _ -> ()
    
    print [Red; Green; Blue]
    

    output

    Green is Not Red
    Blue is Not Red