Allow upcasting in pattern match expressions
I propose we enable some syntax to upcast a bound identifier in a pattern matching expression.
Consider this simple example:
type Base() = member __.SomeBaseMember = "hello"
type Foo() = inherit Base()
type Bar() = inherit Base()
type DU =
| FOO of Foo
| BAR of Bar
let foo = FOO(Foo())
match foo with
| FOO(b)
| BAR(b) -> b.SomeBaseMember
As expected, this code yields a message like:
This expression was expected to have type
'Foo'
but here has type
'Base' at 5,6
I propose we add an upcast syntax so you can write something like:
match foo with
| FOO(b :> Base)
| BAR(b :> Base) -> b.SomeBaseMember
In the pattern match body, the identifier b would then be typed Base.
Alternatives
-
Make no changes to the language and instead structure your code like this:
match foo with
| FOO(b) -> b.SomeBaseMember
| BAR(b) -> b.SomeBaseMember
This works, but when there are many cases, or when b.SomeBaseMember is actually a complex expression, this becomes less than ideal.
A better workaround is to declare an active pattern:
let inline (|Base|) b = b :> Base
match foo with
| FOO(Base b)
| BAR(Base b) -> b
However, this is still not as elegant as an upcast operator built into the pattern matching language.
-
Instead of adding new syntax, use the current type check pattern:
match foo with
| FOO(:? Base as b)
| BAR(:? Base as b) -> b.SomeBaseMember
This currently produces a compiler error:
Type constraint mismatch. The type
'Base'
is not compatible with type
'Foo'
at 5,6
Pros and Cons
Pro: A more elegant syntax to solve the problem above.
Con: Requires implementation in the compiler
Extra informtion
Estimated cost (XS, S, M, L, XL, XXL): S (?)
Affadavit (must be submitted)
Please tick this by placing a cross in the box:
Please tick all that apply:
Allow upcasting in pattern match expressions
I propose we enable some syntax to upcast a bound identifier in a pattern matching expression.
Consider this simple example:
As expected, this code yields a message like:
I propose we add an upcast syntax so you can write something like:
In the pattern match body, the identifier
bwould then be typedBase.Alternatives
Make no changes to the language and instead structure your code like this:
This works, but when there are many cases, or when
b.SomeBaseMemberis actually a complex expression, this becomes less than ideal.A better workaround is to declare an active pattern:
However, this is still not as elegant as an upcast operator built into the pattern matching language.
Instead of adding new syntax, use the current type check pattern:
This currently produces a compiler error:
Pros and Cons
Pro: A more elegant syntax to solve the problem above.
Con: Requires implementation in the compiler
Extra informtion
Estimated cost (XS, S, M, L, XL, XXL): S (?)
Affadavit (must be submitted)
Please tick this by placing a cross in the box:
Please tick all that apply: