type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let add<'a> (x: 'a) (y: 'a) (in_: Interpreter<'a>): 'a =
match in_ with
| RegularInterpreter r ->
x+y |> r
| StringInterpreter r ->
sprintf "(%s + %s)" x y |> r
'a
コンパイル時に解決できないというエラーメッセージは、私には明らかです。上記の作業を行うことが可能かどうかという質問に対する答えは、関数をデータ型に直接追加することを除けば、いいえであると推測しています。しかし、インターフェイスを使用したり、ジェネリック パラメーターを完全に削除したりすることもできます。
編集:マークの返信は実際に私が尋ねたことを行いますが、適切に説明しなかったので質問を拡張させてください. 私がやろうとしているのは、上記の手法を使用して、この投稿で行われたことを模倣することです。これの動機は、インライン化された関数は構成可能性が低いため、回避することです。一般的な引数を特殊化せずにラムダとして渡すことはできません。
ジェネリック引数を持つユニオン型をクロージャーに渡すことで回避できるかもしれないと思っていましたが...
type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let val_ x in_ =
match in_ with
| RegularInterpreter r -> r x
| StringInterpreter r -> r (string x)
let inline add x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ + y in_ |> r
| StringInterpreter r ->
sprintf "(%A + %A)" (x in_) (y in_) |> r
let inline mult x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ * y in_ |> r
| StringInterpreter r ->
sprintf "(%A * %A)" (x in_) (y in_) |> r
let inline r2 in_ = add (val_ 1) (val_ 3) in_
r2 (RegularInterpreter id)
r2 (StringInterpreter id) // Type error.
この最後の行で型エラーが発生します。これを回避する方法はありますか?ただし、構成可能性に制限があるため、関数をインライン化しないことをお勧めします。