In F# I can use pattern matching in a variety of places within the syntax.
For example:
// Given this type...
type SingleCaseUnion = | SingleCaseUnion of int
/// ...I can do this:
let destructureInFunc (SingleCaseUnion n) =
printfn "%d" n
// ...and this:
type DestructureInMethod() =
member t.M(SingleCaseUnion n) =
printfn "%d" n
But I can't work out how to do this:
type DestructureInCtor(SingleCaseUnion n) =
do printfn "%d" n
// type DestructureInCtor(SingleCaseUnion n) =
// ---------------------------------------^
//
// stdin(3,40): error FS0010: Unexpected identifier in type definition. Expected ')' or other token.
Do I have the syntax wrong, or does F# not support pattern matching in constructor parameters?
No, the language spec explicitly says no:
primary-constr-args : attributesopt accessopt (simple-pat, ... , simplepat)
simple-pat :
| ident
| simple-pat : type
As has been pointed out, secondary constructors are allowed pattern-matched parameters, but the difference with the primary constructor is each of the primary's parameters is both a function parameter and a private field declaration.
If F# were to allow pattern matching here, there would be some patterns that would break this one-parameter-one-field relationship.
type DestructureInCtor(SingleCaseUnion _) =
// doesn't declare a private field
or:
type DestructureInCtor((a:int, b:int)) =
// declares two private fields?
It's not inconceivable that this could work but I'm guessing the complexity of allowing pattern matching to be extended to providing field declarations outweighs the benefits.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With