代码之家  ›  专栏  ›  技术社区  ›  Alex Gordon

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

f#
  •  1
  • Alex Gordon  · 技术社区  · 6 年前

    假设我只想表示这8种温度:

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

    我会有一种类型,比如:

    type Temp = 
      | F of int
      | C of float
    

    也许不是用 int float ,我会使用更具体的类型?

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

    1 回复  |  直到 6 年前
        1
  •  2
  •   Ringil    6 年前

    如果你非常确信你只需要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
    

    并始终通过静态成员构建受歧视的工会成员。但这不会阻止某人直接调用构造函数。

    编辑:多亏了amires的建议,一种减少错误调用f的方法是在 打临时工 . 例如,您可以执行以下操作:

    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 .