Are you my type?
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!