创建一个由int和float子集组成的类型

时间:2019-01-16 19:50:43

标签: f#

假设我只想代表这8个温度:

98F
99F
100F
101F
37.0C
37.5C
38.0C
38.5C

我的类型如:

type Temp = 
  | F of int
  | C of float

也许我会使用更具体的类型,而不是使用intfloat

如何创建仅允许8种不同温度的类型?

1 个答案:

答案 0 :(得分:2)

好吧,如果您非常有信心,只需要8个温度,则可以执行以下操作:

type AllowedTemperatures = 
            | F98
            | F99
            | F100
            | F101
            | C370
            | C375
            | C380
            | C385

这就是说,如果您想改用类型Temp,就很难做到这一点,因为它基本上需要具备dependent types的能力,这是F#所不具备的功能(尽管显然我没有尝试过尝试将其添加到语言中的package。您可以尝试这样的事情:

type Temp = 
  | F of int
  | C of float with
  static member fromInt value =
    if value <> 98 && value <> 99 && value <> 100 && value <> 101 then
        raise <| System.ArgumentOutOfRangeException ("value")
    else
        F value
  static member fromFloat value =
    if value <> 37.0 && value <> 37.5 && value <> 38.0 && value <> 38.5 then
        raise <| System.ArgumentOutOfRangeException ("value")
    else
        C value

并始终通过静态成员构造您所区分的工会成员。但这不会阻止某人直接调用构造函数。

编辑:由于AMieres的建议,一种减少误调用F的可能性的方法是将阴影遮盖Temp中的构造函数。例如,您可以执行以下操作:

type Temp = 
  | F of int
  | C of float



let F value  = 
    if value <> 98 && value <> 99 && value <> 100 && value <> 101 then
        raise <| System.ArgumentOutOfRangeException ("value")
    else
        F value

但是,有人仍然可以呼叫Temp.F