虽然将部分函数传递给另一个函数很简单,但如何从函数返回不同签名的部分函数?
这是我正在尝试的基本代码,然后是各种尝试使其工作:
type InitData() =
static member arrayIntAsc count = [|1..count|]
static member seqIntAsc count = {1..count}
static member listIntAsc count = [1..count]
(*more diverse signatures*)
module x =
let getInitDataFun (initData:string) =
match initData.ToLower() with
| "arrayintasc" -> InitData.arrayIntAsc
| "seqintasc" -> InitData.seqIntAsc
| "listintasc" -> InitData.listIntAsc
(*more diverse signatures*)
| _ -> failwithf "InitData function %s not recognized" initData
尝试以各种方式强制使用通用返回签名,但 F# 3.0 总是将 getInitDataFun 返回签名强制为第一个匹配的签名:
let getInitDataFun (initData:string) : 'a -> 'b = ... let getInitDataFun (initData:string) : _ -> _ = ... let getInitDataFun (initData:string) : int -> #(int seq) = ... let getInitDataFun (initData:string) : int -> #('a seq) = ... (*even if I could get (int -> #(int seq)) to work, I would like to return signatures not in this pattern too*)
试过的盒子/拆箱:
| "arrayintasc" -> box InitData.arrayIntAsc
这会编译,但拆箱尝试会引发运行时错误:
未处理的异常:System.InvalidCastException:无法将类型的对象
'RangeInt32@4819-2'
转换为类型'System.Collections.Generic.IEnumerable`1[System.Object]'
尝试将部分函数作为引号返回,但有类似的问题。如果我返回键入的引号,则返回不同的 Expr 签名时会遇到同样的问题。我可以返回无类型的引用,但是我必须在调用方知道返回的无类型表达式的签名。
考虑反射,但基本上是相同的问题,需要在调用时知道实际签名。
也尝试过以各种方式向上转换部分函数。