Reputation: 1941
I was looking at the pattern matching syntax for types in F# described here:
http://msdn.microsoft.com/de-de/library/dd547125.aspx#sectionToggle14
Example from that page (slightly modified):
open System.Windows.Forms
let RegisterControl (control: Control) =
match control with
| :? Button as button -> button.Text <- "Registered."
| :? CheckBox as checkbox -> checkbox.Checked <- false
| _ -> ()
What I don't understand is why we need to introduce a new name ("button", "checkbox") along with the typecheck. If the match succeeded, the compiler should know that "control" has the desired type and could treat it accordingly in the following expression/statement. In other words, why can't I do this:
open System.Windows.Forms
let RegisterControl (control: Control) =
match control with
| :? Button -> control.Text <- "Registered."
| :? CheckBox -> control.Checked <- false
| _ -> ()
This would be similar to the "type guard" feature in TypeScript 1.4.
Is there a good reason why F# doesn't do that [yet]? (Note: I'm running VS 2012.)
Upvotes: 1
Views: 96
Reputation: 13577
This would be trading a consistent model for an inconsistent one.
It's not entirely true that you need to introduce a new name. This works quite well:
match control with
| :? Button -> doButtonyStuff control
| :? CheckBox -> doCheckBoxyStuff control
| _ -> ()
Except of course your control
value stays a Control
in the match case bodies. You only introduce the name when you want to do a typecheck (C#-style is
) and a cast (C#-style as
) in your match pattern.
What you suggest could easily be imagined as having an implicit shadowing of control: Control
you use in the match with another control: Button
after the cast. One problem I see with it is that it has a collateral effect of making the control: Control
inaccessible in the match case bodies. That might not be a big deal in your particular example, but if you're checking against interface types, it might become unwieldy.
No pattern matching constructs do such an implicit thing today. Unless you do so yourself, your bindings don't get shadowed. That's good if you ask me. Explicit is better than implicit.
Upvotes: 2
Reputation: 243061
One obvious reason why you need a new name is when the parameter of match
is an expression:
match some.Method() with
| :? Button -> // What to do here??
Of course, the language could support of the notations. In that case, there is no technical reason why you could not do this, but I think there is a pretty good logical reason for not doing this.
Every value in F# has a location where it is explicitly declared (when you're using a value, you can always go to definition). The values that would be defined using this simplified :? Type
syntax would not really have any declaration
You could say that they are declared at the point where the original variable is declared, but that's wrong - because there, it would have different type.
Or you could say that they are declared in some "hidden way", but that would introduce a completely new concept to the language.
That said, I can see why the syntax is nice and useful. But it does not seem to fit well with the logic of how variables work in F#.
Upvotes: 4