是否可以通过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

是否可以通过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 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
where
Z
会导致一个c'tor调用。很抱歉,正如我所说:我看不到任何方法可以按照你想要的方式来做。但是这对于评论来说太多了(不可读,我试过了)-要我删除答案吗?PS:我想也许你想要用测量单位得到的类型安全性,你的答案是好的。这不是我梦寐以求的银弹解决方案。请不要将其作为他人灵感的来源删除;-)答案很简单:没有。有没有其他方法可以在F#中创建自定义后缀运算符?
let p = 5 |> pixel
let var1 = 10 |> Pixel
let var2 = Unset