是否有任何技巧可以在不丢失漂亮打印的情况下将单元硬编码到记录字段中?

Are there any tricks for hard coding units into record fields without losing pretty printing?

我希望将单元硬编码到我的记录字段中。目前,我重写了 ToString() 方法并使用了 [StructuredFormatDisplay("{AsString}")] 属性。这已经奏效了,除了不幸的是我丢失了 FSharp 在该记录嵌套到的类型上的漂亮打印(主要是偏移)。话虽如此,我想知道是否有人知道完成此操作的任何技巧。

基本上我有这种类型:

type SteelMaterial =
    {Fy : float<ksi>;
     Fu : float<ksi>;
     E : float<ksi>;}

并希望它像这样打印出来:

SteelMaterial = {Fy = 50.0 <ksi>;
                 Fu = 60.0 <ksi>;
                 E = 29000.0 <ksi>;}

像这样,当嵌套时:

Section = {Section = "Section 1";
           Material = {Fy = 50.0 <ksi>;
                       Fu = 60.0 <ksi>;
                       E = 29000.0 <ksi>;};
           Transformations = null;}

我之所以这样做是为了在通过 F# 格式(通过 (*** include-value: mySection **))、Ifsharp 或 Azure Notebooks 生成计算时记录单位。

更新

我最初没有包含我的实现,因为我认为它不会使问题更加清晰。如果有人想知道,就在这里。

[<StructuredFormatDisplay("{AsString}")>]
type SteelMaterial =
    {
    Fy : float<ksi>
    Fu : float<ksi>
    E : float<ksi>
    }   
    
    static member create (Fy, Fu, E) =
        {Fy = Fy; Fu = Fu; E = E}

    override this.ToString() = 
        sprintf "Steel Material =\r\n{Fy = %f <ksi>;\r\nFu = %f <ksi>;\r\nE = %f <ksi>;}"
            this.Fy this.Fu this.E

    member this.AsString = this.ToString()

看起来我可以通过将单元包装在 DU 中并覆盖 ToString() 方法来获得我正在寻找的东西。

[<Measure>] type ksi

[<StructuredFormatDisplay("{AsString}")>]
type Ksi =
    | Ksi of float<ksi>

    override this.ToString() =
        match this with
        | Ksi value -> System.String.Format("{0:0.0####} <ksi>", value)

    member this.AsString = this.ToString()

    member this.ksi =
        match this with
        | Ksi value -> value


type SteelMaterial =
    {Fy : Ksi;
     Fu : Ksi;
     E : Ksi;}

let mySteelMaterial =
    {Fy = Ksi(50.0<ksi>);
     Fu = Ksi(60.0<ksi>);
     E = Ksi(29000.0<ksi>)}

这有一些好处,包括能够在 Ksi 类型上进行模式匹配和打印我正在寻找的单位。缺点是 DU 中包装值带来的缺点,其中包括用户需要键入不太简洁的 Ksi(10.0<ksi>),然后需要通过“.ksi”访问值。