Did you know there was more to the type matching operator than just pattern matching and exception handling?

The type matching operator is defined thus: :? It can be used by pattern matching to match on a specific type. For example, you might want to test that an object is a certain type or deal with an object being one of several different types. Pattern matching on types is your friend here:

match symbolUse.Symbol with
| :? FSharpMemberOrFunctionOrValue
| :? FSharpUnionCase
| :? FSharpEntity
| :? FSharpField
| :? FSharpGenericParameter
| :? FSharpActivePatternCase
| :? FSharpParameter
| :? FSharpStaticParameter ->
    match getSymbolDeclarationLocation symbolUse currentFile solution with
    | SymbolDeclarationLocation.External -> false
    | SymbolDeclarationLocation.Unknown -> false
    | _ -> true
| _ -> false

During pattern matching you can also use the as assignment operator to assign a named binding to the match so you can use it directly. This is somewhat akin to using is and as in C#, or using an as and then a null check. Yuck! None of that kind of thing in F#:

let isPrivateToFile = 
    match symbolUse.Symbol with
    | :? FSharpMemberOrFunctionOrValue as m -> not m.IsModuleValueOrMember
    | :? FSharpEntity as m -> m.Accessibility.IsPrivate
    | :? FSharpGenericParameter -> true
    | :? FSharpUnionCase as m -> m.Accessibility.IsPrivate
    | :? FSharpField as m -> m.Accessibility.IsPrivate
    | _ -> false

It can also be used in exception handing to match a specific type of exception, as in this example where TimeoutExceptions are caught:

member x.GetDeclarationSymbols(line, col, lineStr) = 
    match infoOpt with 
    | None -> None
    | Some (checkResults, parseResults) -> 
        let longName,residue = Parsing.findLongIdentsAndResidue(col, lineStr)
        // Get items & generate output
        try
            let results = 
                Async.RunSynchronously (checkResults.GetDeclarationListSymbols(Some parseResults, line, col, lineStr, longName, residue, fun _ -> false), timeout = ServiceSettings.blockingTimeout )
            Some (results, residue)
        with :? TimeoutException -> None

A final use for :? that people either don’t tend to use or know about, is during a normal expression assignment. In this example item :? DotNetProject would evaluate to true when item is a DotNetProject.

override x.SupportsItem(item:IBuildTarget) =
    item :? DotNetProject

Although not used that often I find the :? operator to be really useful.

As usual F# helps to keep things short, succinct, and sweet!

Until next time!


Essential listening:

Suicidal Tendencies - The Art Of Rebellion
Suicidal Tendencies - The Art Of Rebellion
Rise Against - The Black Market
Rise Against - The Black Market