【发布时间】:2017-12-27 11:48:41
【问题描述】:
即使键入了基础值,我的 F# 代码的某些函数也会接收装箱为对象的值。如果该值是可区分的联合,则无法将其拆箱回其 F# 类型。这是一个简单的例子:
type Result<'TOk,'TError> =
| Ok of 'TOk
| Error of 'TError
type ResultA = Result<string, int>
let a = Ok "A"
let o = box a
match o with
| :? ResultA -> printfn "match ResultA"
// | :? ResultA.Ok -> printfn "match" // doesn't compile
| _ when o.GetType().DeclaringType = typedefof<ResultA> -> printfn "match via reflection"
| _ -> printfn "no match"
此示例的输出是“通过反射匹配”,ResultA 永远不会匹配,因为装箱的值是不同的 CLR 类型 - Result.Ok。由于 F# 可区分联合案例表示为其自己的类型,因此装箱值与类型 ResultA 不匹配。此外,不可能将其与 ResultA.OK 匹配,因为在 F# 代码中它不是合法类型。唯一的选择似乎是使用反射手动实例化一个值,这既低效又愚蠢,因为该值已经实例化,它就在这里,一旦装箱就无法在 F# 代码中访问它。
我是否忽略了什么?有没有更直接的方法来拆箱 F# 区分联合值?
【问题讨论】:
标签: reflection f# discriminated-union