8

是否可以将常量字段值添加到 F# 区分联合?

我可以做这样的事情吗?

type Suit
  | Clubs("C")
  | Diamonds("D")
  | Hearts("H")
  | Spades("S")
  with
    override this.ToString() =
      // print out the letter associated with the specific item
  end

如果我正在编写 Java 枚举,我会向构造函数添加一个私有值,如下所示:

public enum Suit {
  CLUBS("C"),
  DIAMONDS("D"),
  HEARTS("H"),
  SPADES("S");

  private final String symbol;

  Suit(final String symbol) {
    this.symbol = symbol;
  }

  @Override
  public String toString() {
    return symbol;
  }
}
4

3 回答 3

11

只是为了完整起见,这意味着:

type Suit = 
  | Clubs
  | Diamonds
  | Hearts
  | Spades
  with
    override this.ToString() =
        match this with
        | Clubs -> "C"
        | Diamonds -> "D"
        | Hearts -> "H"
        | Spades -> "S"
于 2012-04-30T13:03:03.597 回答
6

最接近您的要求的是F# enums

type Suit =
    | Diamonds = 'D'
    | Clubs = 'C'
    | Hearts = 'H'
    | Spades = 'S'

let a = Suit.Spades.ToString("g");;
// val a : string = "Spades"

let b = Suit.Spades.ToString("d");; 
// val b : string = "S"

F# 枚举的问题在于非详尽的模式匹配。操作枚举时,您必须使用通配符 ( _) 作为最后一个模式。因此,人们往往更喜欢可区分的联合并编写显式ToString函数。

另一种解决方案是在构造函数和相应的字符串值之间进行映射。这在我们需要添加更多构造函数时很有帮助:

type SuitFactory() =
    static member Names = dict [ Clubs, "C"; 
                                 Diamonds, "D";
                                 Hearts, "H";
                                 Spades, "S" ]
and Suit = 
  | Clubs
  | Diamonds
  | Hearts
  | Spades
  with override x.ToString() = SuitFactory.Names.[x]
于 2012-04-30T12:56:43.493 回答
1

很确定你不能,但是编写一个模式匹配的函数然后组合这两件事是微不足道的

于 2012-04-30T12:42:36.147 回答