2

以下代码失败:

open Microsoft.FSharp.Reflection
open Microsoft.FSharp.Quotations
let (empty,cons) =
    FSharpType.GetUnionCases(typeof<List<_>>)
    |> (fun cases ->
        cases |> Array.find (fun c -> c.Name = "Empty"),
        cases |> Array.find (fun c -> c.Name = "Cons"))

let valuesToList values =
    values
    |> List.map (fun v -> Expr.Value(v))
    |> List.fold
        (fun l v -> Expr.NewUnionCase(cons, [v;l]))
        <@@ List.empty<int> @@>

[1;2;3]
|> valuesToList

有这个特例:

System.ArgumentException: Type mismatch when building 'sum': incorrect argument type for an F# union. Expected 'System.Object', but received type 'System.Int32'.

如何指定 Cons 联合案例的通用参数类型?

4

1 回答 1

3

问题出在GetUnionCases(typeof<List<_>>). 通配符被推断为obj. 因此错误

应为“System.Object”,但收到类型“System.Int32”。

这是一个工作版本。

let valuesToList (values: list<'a>) =
    let empty, cons =
        FSharpType.GetUnionCases(values.GetType())
        |> (fun cases ->
            cases |> Array.find (fun c -> c.Name = "Empty"),
            cases |> Array.find (fun c -> c.Name = "Cons"))
    values
    |> List.map Expr.Value
    |> List.fold
        (fun l v -> Expr.NewUnionCase(cons, [v;l]))
        <@@ List.empty<'a> @@>
于 2015-05-20T15:23:18.893 回答