如何通过为F#(无反射)中的每个惰性对象创建值来转换包含惰性对象的异构数组

如何通过为F#(无反射)中的每个惰性对象创建值来转换包含惰性对象的异构数组,f#,lazy-evaluation,F#,Lazy Evaluation,我怎样才能转变 let args : Object[] = [| lazy 7; "text"; lazy "lazytext" |] 进入 这不起作用: let createvalue<'t> (v: Object) : Object = match v with | :? Lazy<'t> as x -> x.Value :> Object | x -> x args |> A

我怎样才能转变

let args : Object[] = [| lazy 7; "text"; lazy "lazytext" |]
进入

这不起作用:

let createvalue<'t> (v: Object) : Object =
    match v with
    | :? Lazy<'t> as x -> x.Value :> Object
    | x -> x

args |> Array.map createvalue

但是有没有一个干净的直截了当的方法呢?

只要让
createvalue
内联函数就行了,它应该可以工作。

我认为这不能用异类
惰性x.Value干净地完成
|x->x
您不能这样做

让我们看看你使用的东西的类型:

let args : Object[] = [| lazy 7; "text"; lazy "lazytext" |]

let createValue<'t> (v: obj) : obj = ...

module Array =
    let inline map (mapping: 't -> 'u) (array:'t[]) = ...
这表明Array.map在本例中只接受了一个从
obj->obj
开始的函数。但是您的
createValue x.Value:>对象
|x->x
您还可以传递createValue的其他具体版本。例如,如果您使用
args |>Array.map createvalue
,则它可以正确地用于所有int实例,但不能用于其他任何实例

如果您知道lazy可以包含的类型,您可以执行以下操作:

let createvalue (v: obj) : obj =
    match v with
    | :? Lazy<int> as x -> x.Value :> obj
    | :? Lazy<string> as x -> x.Value :> obj
    | x -> x
让createvalue(v:obj):obj=
匹配
| :? 懒惰为x->x。值:>obj
| :? 懒惰为x->x。值:>obj
|x->x

但如果你不这样做,我担心你会陷入反思,或者像brianberns建议的那样改变你的方法。

不,这不起作用。已经考虑过了——这也成为了createvalue。您可以自己尝试通过使数组异构,您已经删除了其元素的类型。由于您坚持在编译时不知道类型,所以了解它们的唯一其他方法是在运行时,这就是反射所做的。有趣的想法。实际上,简单的api是必须的。我更倾向于使用反射,因为无论如何日志记录都是IO,所以反射性能不是一个问题。thx用于此创造性输入。
let args : Object[] = [| lazy 7; "text"; lazy "lazytext" |]

let createValue<'t> (v: obj) : obj = ...

module Array =
    let inline map (mapping: 't -> 'u) (array:'t[]) = ...
let args : Object[] = [| lazy 7; "text"; lazy "lazytext" |]

let createValue<'t> (v: obj) : obj =
    match v with
    | :? Lazy<'t> as x -> x.Value :> Object
    | x -> x

module Array =
    let inline map (mapping: obj -> obj) (array:obj[]) = ...
let createValue (v: obj) : obj =
    match v with
    | :? Lazy<obj> as x -> x.Value :> Object
    | x -> x
let createvalue (v: obj) : obj =
    match v with
    | :? Lazy<int> as x -> x.Value :> obj
    | :? Lazy<string> as x -> x.Value :> obj
    | x -> x