我很确定这是不可能的,但我想我会仔细检查一下。我想我正在尝试模仿打字稿的联合类型。
我有一个类型
type StringOrInt =
| String of string
| Int of int
Run Code Online (Sandbox Code Playgroud)
然后是一个函数
let returnSelf (x: StringOrInt) = x
Run Code Online (Sandbox Code Playgroud)
目前该函数必须像这样调用
returnSelf (String "hello")
Run Code Online (Sandbox Code Playgroud)
是否可以做
returnSelf "hello"
Run Code Online (Sandbox Code Playgroud)
并推断它是一个有效的 StringOrInt?
目前还不支持开箱即用,但可以实现相当简单的通用转换方法。
给出一个示例函数:
let call v = (* v has inferred type StringOrInt *)
match v with
| String s -> printfn "called a string %s" s
| Int i -> printfn "called an int %i" i
Run Code Online (Sandbox Code Playgroud)
我们最终可以这样称呼它:
(* % is a unary prefix operator *)
call %"abc"
call %1
Run Code Online (Sandbox Code Playgroud)
我们需要提供一些方法来告诉如何将普通的 string/int 转换为StringOrInt类型。这可以通过示例约定调用来使用:
type StringOrInt =
| String of string
| Int of int
static member inline From(i: int) = Int i
static member inline From(s: string) = String s
Run Code Online (Sandbox Code Playgroud)
这里我们的可区分联合提供了两个负责强制转换的静态方法。由于它们对应于相同的命名约定,因此我们可以将它们与 F# 静态解析的泛型类型参数一起使用 - 这些泛型在编译时解析,不像 .NET 泛型也存在于运行时 - 来创建转换函数(或运算符) ):
(* casting operator *)
let inline (~%) (x: ^A) : ^B =
(^B : (static member From: ^A -> ^B) x)
Run Code Online (Sandbox Code Playgroud)
这样,您就可以%在任何以静态From方法形式实现转换机制的类型上使用前缀运算符。