F#中的计量单位“类型”

时间:2010-12-07 19:30:21

标签: c# f#

我正在为F#中的测量单位编写转换函数。有关值的信息来自ASP.NET Web应用程序。

我正在创建的函数定义如下:

let convert (x:float<_>) (toType : string) =
  // Do conversion here.

我遇到的第一个问题涉及toType:字符串定义。有什么方法可以让我定义它来接受float<_>类型...特别是来自Web应用程序? (我知道它是基于Andrew Kennedy's excellent articles的CLR的一部分,但我不知道如何在函数中一般地定义它。

感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:2)

由于测量类型在运行时被删除,我认为不可能做到你想要的。特别是,对于度量类型,没有类似于运行时类型测试(例如F#(:?)运算符)。

您希望在convert函数中实现什么类型的逻辑?

<强>更新

根据您提供的其他信息,以下是一些更多想法:

  1. F#的衡量单位的重点是在编译时强制以适合单位的方式使用数量。这意味着您无法编写函数convert : float<'t> -> float<'u> - 如果您的用户尝试执行无意义的转换(例如将某些内容从float<kg>转换为float<m/s^2>)会发生什么? F#的单位类型的工作是静态地防止这样的转换。

  2. 但是,如果你有一个已知的可互换类型列表,你可以通过使用乘法来执行导致非单元泛型返回类型的转换:

    [<Measure>] type m
    [<Measure>] type km
    
    
    let convert (f:float) (s:string) : float<m> =
      match s with
      | "m" -> f * 1.0<m>
      | "km" -> f * 1.0<km> * 1000.0<km/m>
      | _ -> failwith (s |> sprintf "Unknown unit of measure: %s")
    

    这总是以米为单位返回结果,以无单位数量和它所代表的单位名称为准。

答案 1 :(得分:2)

如果您只想阅读“2.0英尺”和“5.0米”,那么

  • 你应该编写解析字符串并执行一些条件逻辑的代码(例如,如果“ft”然后变成float<ft>或其他什么)

  • 将数据转换为F#类型系统后,您可以采用类型安全的方式进行操作

这是每个想要从外部世界获取强类型数据的应用程序的典型代表;有一个输入组件必须解析并验证输入并将其存储到强类型数据结构中,但程序此后可以使用该数据。

(在任何库中都没有神奇的解析器/输入验证器,只需为您的数据类型执行此操作。)