是否可以通过F#中的度量单位标记创建有区别的并集?
是否可以通过F#中的测量单位标记创建有区别的联合类型 我想写如下的东西:是否可以通过F#中的度量单位标记创建有区别的并集?,f#,units-of-measurement,discriminated-union,F#,Units Of Measurement,Discriminated Union,是否可以通过F#中的测量单位标记创建有区别的联合类型 我想写如下的东西: type DomainObject = | Pixel of int | ScaledPixel of int | Centimeter of float | Unset let var1 = 10<px> // should equal: let var1 = Pixel(10) let var2 = 0<us> // should equal: let
type DomainObject =
| Pixel of int
| ScaledPixel of int
| Centimeter of float
| Unset
let var1 = 10<px> // should equal: let var1 = Pixel(10)
let var2 = 0<us> // should equal: let var2 = Unset
let process sth =
match sth with
| Pixel(p) -> ...
| Centimeter(c) -> ...
// etc.
类型域对象=
|整数像素
|整型缩放像素
|厘米浮子
|取消
设var1=10//应等于:设var1=Pixel(10)
设var2=0//应等于:设var2=Unset
让我们来处理某事=
搭配
|像素(p)->。。。
|厘米(c)->。。。
//等等。
有了数字文字,这样的事情是可能的。但是我们只能使用少量的文本,比如。我认为这种特殊的组合是不可能的,但是如果您愿意,您可以使用智能构造函数:
module Domain =
[<Measure>] type px
[<Measure>] type spx
[<Measure>] type cm
// ...
type DomainObject =
| Pixel of float<px>
| ScaledPixel of float<spx>
| Centimeter of float<cm>
| Unset
let inline pixel f = Pixel <| float f * 1.0<px>
let inline scaledPixel f = ScaledPixel <| float f * 1.0<spx>
let unset = Unset
// ...
let var1 = pixel 10
let var2 = unset
let process sth =
match sth with
| Pixel(p) -> ...
| Centimeter(c) -> ...
// etc.
但我觉得写起来很难看
let p = 5Q
而不是
let p = pixel 5
或
正如我在评论中所说,简单的答案是否定的 在某种程度上,您试图滥用一个F#特性(度量单位)来模拟可能存在于其他语言中的特性(后缀运算符),这可能是一件不好的事情,因为(即使有可能),生成的代码将非常混乱 如果您只是想颠倒参数的顺序,使数字位于装置名称之前,则可以使用管道操作符并写入:
let var1 = 10 |> Pixel
let var2 = Unset
这基本上为您提供了一种编写“后缀运算符”的方法,但使用标准的F#习惯用法。这实际上不是我想要的。我看不出写作有什么好处:
let var1=pixel 10
而不是let var1=pixel 10
。我一直在寻找一个后缀版本,就像数字文字一样,可以写let var1=10Z
whereZ
会导致一个c'tor调用。很抱歉,正如我所说:我看不到任何方法可以按照你想要的方式来做。但是这对于评论来说太多了(不可读,我试过了)-要我删除答案吗?PS:我想也许你想要用测量单位得到的类型安全性,你的答案是好的。这不是我梦寐以求的银弹解决方案。请不要将其作为他人灵感的来源删除;-)答案很简单:没有。有没有其他方法可以在F#中创建自定义后缀运算符?
let p = 5 |> pixel
let var1 = 10 |> Pixel
let var2 = Unset