F#:键入匹配和活动模式

Mil*_*oDC 2 f# pattern-matching active-pattern

鉴于以下内容:

type IFruit = interface end

type Avocado = { color : string; age : int } interface IFruit

let (|AvocadoTexture|) (a : Avocado) = if a.age < 7 then "firm" else "mushy"
Run Code Online (Sandbox Code Playgroud)

...为什么这样做:

let texture (f : IFruit) =
    match f with
    | :? Avocado as a -> if a.age < 7 then "firm" else "mushy"
    | _ -> String.Empty
Run Code Online (Sandbox Code Playgroud)

......但不是吗?

let texture (fruit : IFruit) =
    match fruit with
    | AvocadoTexture t -> t    // "The type IFruit does not match the type Avocado"
    | _ -> String.Empty
Run Code Online (Sandbox Code Playgroud)

Tea*_*Dev 6

fruit可以是任何IFruit,但AvocadoTextureActive模式只接受特定的实现Avocado,根据类型注释a.如果您希望Active Pattern接受任何IFruit,但只返回一个有用的值Avocado,您可以将其设为部分:

let (|AvocadoTexture|_|) (f : IFruit) =
    match f with
    | :? Avocado as a ->
        if a.age < 7 then "firm" else "mushy"
        |> Some
    | _ -> None
Run Code Online (Sandbox Code Playgroud)

现在你的texture功能可以按你的需要工作:

let texture (fruit : IFruit) =
    match fruit with
    | AvocadoTexture t -> t
    | _ -> String.Empty
Run Code Online (Sandbox Code Playgroud)