部分関数を別の関数に渡すのは簡単ですが、関数からさまざまなシグネチャの部分関数を返すにはどうすればよいでしょうか?
これが私が試みている基本的なコードであり、その後にそれを機能させるためのさまざまな試みが続きます:
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 署名を返すことで同じ問題が発生しました。型なしの引用符を返すことはできますが、呼び出し側で、返された型なしの式の署名を知る必要があります。
リフレクションと見なされますが、呼び出すときに実際の署名を知る必要があるという基本的に同じ問題です。
部分関数もさまざまな方法でアップキャストしてみました。