如何通过值来进行递归区分联合?

时间:2013-04-15 01:12:23

标签: f#

在F#中,是否可以根据类型和值来区分联合?

这是尝试在不知道语法应该是什么样的情况下表达这一点。

type Foo =
    | A of int * Foo
    | B of string where B.name = "1" * Foo
    | C of string where C.name = "2" * Foo
    | Empty

1 个答案:

答案 0 :(得分:5)

我不完全确定你想要实现的目标。但是,如果您想要创建一个具有name属性的类型,当类型为B时为“1”,而当C时为“2”,那么您可以添加成员:

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!"

如果您希望在模式匹配中使用数字,则可以定义活动模式。假设您的类型只有AB(具有名称):

type Foo = 
  | A of int
  | B of string * Foo

现在,您可以编写一个活动模式,以便区分名称为“1”的AB和名称为“2”的B

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"

如果您现在拥有值foo,则可以针对这三种情况进行模式匹配:

match foo with
| A n -> ...
| B1 subfoo -> ...
| B2 subfoo -> ...