【问题标题】:How to pattern-match when something is NOT of a particular type当某些东西不是特定类型时如何进行模式匹配
【发布时间】:2011-07-02 01:47:51
【问题描述】:

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

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

谢谢!

【问题讨论】:

    标签: f# functional-programming pattern-matching active-pattern


    【解决方案1】:

    虽然没有对Not 的直接支持,但您可以使用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]
    

    输出

    Green is Not Red
    Blue is Not Red
    

    【讨论】:

    • 非常好,正是我需要的。谢谢!
    【解决方案2】:

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

    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-10-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多