3

我们都习惯于对某些特定类型的情况进行模式匹配,例如

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

但是,当某些东西不是特定类型时,我该如何匹配呢?例如,

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

谢谢!

4

2 回答 2

4

我认为处理这个问题的常用方法是首先编写一个明确排除您不想要的情况的子句。然后您可以使用_来处理所有剩余的情况(您需要为要排除的情况编写一些代码,但无论如何都需要编写以使模式匹配完成):

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

这绝对是一种解决方法,但恐怕这是你能做的最好的。如果您想排除多种情况,可以编写如下内容:

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"

无论如何,这是一个非常有趣的问题——我想知道是否可以用一些特殊的模式来扩展模式语言来表达否定......有趣的是,这不是可以直接使用活动模式编写的东西。

于 2011-02-22T15:03:10.457 回答
4

虽然没有直接支持,Not但您可以使用部分活动模式

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]

输出

Green is Not Red
Blue is Not Red
于 2011-02-22T17:12:20.957 回答