如果我有一个受歧视的联盟
type Result<'T,'U> =
| Success of 'T
| Failure of 'U
然后我可以创建一个模式匹配函数来测试成功
let success = function
| Success(_) -> true
| _ -> false
我可以将其创建为单线,就像这样吗?
let success = fun x -> x = Success(_)
这最后一行没有编译,但我认为它证明了我的意图
答案 0 :(得分:5)
没有简单的方法可以这样做,但你可以通过反思来做到这一点。使用this answer中的isUnionCase
函数,我们可以写:
let success = isUnionCase <@ Success @>
对于这个特殊情况,我认为success
函数非常简洁,足以被认定为单行:
let success = function Success _ -> true | _ -> false
正如@Daniel所说,应该公开编译器生成的Is*
函数。用户语音上有related suggestion,也许您应该投票,以便在F#4.0中实现。
答案 1 :(得分:4)
编译后的表单为每个案例公开了IsSuccess/IsFailure
等属性,但不幸的是,在这种情况下,它们仅在其他.NET语言中可用。你拥有的就是它的好处。
有趣的是,尝试定义这些成员也不会有用:
type Result<'T,'U> =
| Success of 'T
| Failure of 'U
member this.IsSuccess = true //ERROR
无法定义成员'IsSuccess',因为名称'IsSuccess' 冲突与工会案例'成功'的默认扩充 这种类型或模块
如果它们存在于F#中,因为无法定义具有相同名称的成员,它们也应该可用。也许拉动请求的候选人?
答案 2 :(得分:0)
您可以创建一个可以帮助您的通用功能:
let ItIsSucess value =
match value with
| Success(_) -> true
| _ -> false
比你能写的......像:
let expr = ...
if ItIsSucess expr than
"do something"
else
"do nothing"
你也可以考虑像一个更通用的函数思考,并使用反射来测试任何类型。但这并不容易,我不建议为这个简单的任务做到这一点。反射可能会破坏F#中类型安全的好处,因此请注意是否使用它。
答案 3 :(得分:0)
注意到选项类型 具有IsSome
和IsNone
属性,我查看了源代码,发现该类型已装饰[<DefaultAugmentation(false)>]
。< / p>
将该属性应用于Result类型,我发现我能够定义IsSuccess
属性。此属性“关闭为该类型生成的公共语言基础结构(CLI)类生成标准帮助程序成员测试程序,构造函数和访问程序成员”,因此请谨慎使用。
您也可以从Option类型中获取另一个提示,并定义一个Result模块,定义isSuccess
和isFailure
函数:
module Result =
let isSuccess = function Success _ -> true | _ -> false
let isFailure = function Failure _ -> true | _ -> false