Reputation: 9009
In F# is it possible to have a discriminated union based on both a type and a value?
Here's an attempt at expressing this without knowing what the syntax should look like.
type Foo =
| A of int * Foo
| B of string where B.name = "1" * Foo
| C of string where C.name = "2" * Foo
| Empty
Upvotes: 0
Views: 340
Reputation: 243041
I'm not entirely sure what you're trying to achieve. But, if you want to create a type that will have a name
property when which is "1" when the type is B
and "2" when it is C
, then you can add a member:
type Foo =
| A of int * Foo
| B of Foo
| C of Foo
| Empty
member x.Name =
match x with
| B _ -> "1"
| C _ -> "2"
| _ -> failwith "Name is not available!"
If you were hoping to use the numbers in pattern matching, then you can define an active pattern. Say you have a type with just A
or B
(which has a name):
type Foo =
| A of int
| B of string * Foo
Now you can write an active pattern that lets you distinguish between A
, B
with name "1" and B
with name "2":
let (|A|B1|B2|) x =
match x with
| A n -> A n
| B("1", foo) -> B1 foo
| B("2", foo) -> B1 foo
| _ -> failwith "Invalid B"
If you now have a value foo
, you can pattern match against these three cases:
match foo with
| A n -> ...
| B1 subfoo -> ...
| B2 subfoo -> ...
Upvotes: 5