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)
开发者_如何学Python
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!
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
I think the usual way to deal with this is to first write a clause that explicitly excludes the cases you don't want. Then you can use _ to handle all remaining cases (You need to write some code for the case you want to exclude, but that needs to be written anyway to make the pattern matching complete):
match x with
| Y _ :: tail -> ()
| _ :: tail -> // List.head(x) is definitely not a Y
This definitely feels like a workaround, but I'm afraid that's the best you can do. If you wanted to exclude multiple cases, you can write something like:
match x with
| (Y _ | (Z (1 | 2 | 3 | 4)) :: tail -> ()
| _ :: tail -> // Excludes all "Y x" and "Z n when n \in 1,2,3,4"
Anyway, this is a very interesting question - I'm wondering if the language of patterns could be extended with some special pattern for expressing negation... Interestingly, this is not something that could be directly written using active patterns.
加载中,请稍侯......
精彩评论