Types F#强制转换/将自定义类型转换为基元

Types F#强制转换/将自定义类型转换为基元,types,casting,f#,primitive,Types,Casting,F#,Primitive,我已经用自定义F#类型设计了我的应用程序域,但现在看来,当我想实际使用数据执行各种任务时,这些自定义类型将是一个PITA。。。i、 e.使用依赖于原语的其他库等将值写入CSV文件 例如,我有这样一个自定义类型(用作其他较大类型的构建块): 但这样的代码不起作用: let x = CT32(1.2) let y = float x //error: The type "CT32" does not support a conversion... let z = x.ToString() //wri

我已经用自定义F#类型设计了我的应用程序域,但现在看来,当我想实际使用数据执行各种任务时,这些自定义类型将是一个PITA。。。i、 e.使用依赖于原语的其他库等将值写入CSV文件

例如,我有这样一个自定义类型(用作其他较大类型的构建块):

但这样的代码不起作用:

let x = CT32(1.2)
let y = float x //error: The type "CT32" does not support a conversion...
let z = x.ToString() //writes out the namespace, not the value (1.2)

我曾尝试使用box/unbox和Convert.ToString()以及两个F#casting操作符,但它们似乎都不允许我访问类型中包含的基本原语值。有没有一种简单的方法来获取自定义类型中的基元值,因为到目前为止,这些基元值都是令人头痛的问题,而不是实际有用的问题。

您的
类型CT32
是一个区分的并集,具有一个大小写标识符
CT32 float
。它不是一个
别名
to float类型,所以不能将其强制转换为float。 要从中提取值,可以使用模式匹配(这是最简单的方法)


另一种选择是(如果您的自定义类型是数字的),您可以使用度量单位,它们没有运行时开销(我相信有区别的联合被编译为类),但在编译时提供类型安全性

添加对
float
的支持很简单:

type CT32 = CT32 of float with
    static member op_Explicit x =
        match x with CT32 f -> f

let x = CT32(1.2)
let y = float x

您还可以使用
内联解构
,它不需要对类型本身进行修改

例如:


谢谢你,彼得,你就是那个人!不久前,我遵循了一个关于使用类型进行设计的F#教程,并没有完全理解如何使用这些单例DU。您还可以实现
op#u Explicit
member来使用模式匹配来进行常规
float
cast,正如下面所建议的@RCH。问题是,为什么不是每个DU成员都使用这种方法呢。
type CT32 = CT32 of float
let x = CT32(1.2)

let CT32toFloat = function CT32 x -> x
let y = CT32toFloat x
let z = y.ToString()
type CT32 = CT32 of float with
    static member op_Explicit x =
        match x with CT32 f -> f

let x = CT32(1.2)
let y = float x
type EmailAddress = EmailAddress of string
let email = "foo" |> EmailAddress
let (EmailAddress email') = email // you can now access the email' string value