刚开始我的F#之旅,是否可以定义一个受限于特定字符串值集的类型? F.ex.它只能表示值"Foo"
,"Bar"
和"Baz"
,尝试为其分配任何其他值将导致错误,甚至在编译时更好地失败。
更新: 到目前为止,我考虑过创建一个字符串类型并使用create函数:
type Constrained = string
let createConstrained (constrained : Constrained) =
match constrained with
| "foo" -> constrained
| "bar" -> constrained
| "baz" -> constrained
| _ -> failwith "Can be only foo, bar or baz"
接下来,我考虑使用DU和某种函数,它根据选项返回字符串(是正确的名称吗?):
type Constrained = FOO | BAR | BAZ
let constrainedString constrained =
match constrained with
| FOO -> "foo"
| BAR -> "bar"
| BAZ -> "baz"
| _ -> failwith "Can only be foo, bar or baz"
不确定是否有任何一种方法可以使用。
答案 0 :(得分:4)
正如人们在评论中指出的那样,一般来说,听起来你在问F#是否具有称为细化类型的语言特征;它没有。
但是,在您的特定示例中,您可以简单地定义一个有区别的联合并覆盖其ToString
方法:
type Constrained =
Foo | Bar | Baz
override this.ToString () =
match this with
| Foo -> "Foo"
| Bar -> "Bar"
| Baz -> "Baz"
这样您就可以使用内置的Constrained
函数将任意string
值转换为所需的字符串:
> string Foo;;
val it : string = "Foo"
> string Baz;;
val it : string = "Baz"
如果您发现上述实施包含太多样板文件,则可以将"%A"
格式与sprintf
一起使用:
type Constrained =
Foo | Bar | Baz
override this.ToString () = sprintf "%A" this
由于"%A"
使用反射,它会变慢,但行为是相同的。有a suggestion在这个领域提供更好的语言支持。