测试值是否是受歧视联合的特定实例

Pet*_*ete 1 f#

如果我有一个受歧视的联盟

type Result<'T,'U> =
| Success of 'T
| Failure of 'U
Run Code Online (Sandbox Code Playgroud)

然后我可以创建一个模式匹配函数来测试成功

let success = function
    | Success(_) -> true
    | _ -> false
Run Code Online (Sandbox Code Playgroud)

我可以将它创建为单线,就像这样吗?

let success = fun x -> x = Success(_)
Run Code Online (Sandbox Code Playgroud)

最后一行不能编译,但我认为它证明了我的意图

Dan*_*iel 5

编译后的表单公开了类似于IsSuccess/IsFailure每种情况的属性,但不幸的是,对于这种情况,它们仅在其他 .NET 语言中可用。你所拥有的就像它得到的一样好。

有趣的是,尝试定义这些成员也不起作用:

type Result<'T,'U> =
    | Success of 'T
    | Failure of 'U
    member this.IsSuccess = true //ERROR
Run Code Online (Sandbox Code Playgroud)

无法定义成员“IsSuccess”,因为名称“IsSuccess”与此类型或模块中联合案例“Success”的默认扩充相冲突

在我看来,如果它们存在于 F# 中,因为无法定义具有相同名称的成员,它们也应该可用。也许是拉取请求的候选人?


pad*_*pad 5

没有简单的方法可以这样做,但你可以通过反思来做到这一点.使用这个答案中isUnionCase函数,我们可以写:

let success = isUnionCase <@ Success @>
Run Code Online (Sandbox Code Playgroud)

对于这个特殊情况,我认为该success功能非常简洁,可以被认定为单行:

let success = function Success _ -> true | _ -> false
Run Code Online (Sandbox Code Playgroud)

正如@Daniel所说,Is*应该公开编译器生成的函数.关于用户语音有一个相关的建议,也许你应该投票,以便它在F#4.0中实现.