次のコードでは、変数の型を使用して最終的に関数に渡される汎用変数としてテンプレート化されたクラスをインスタンス化したいと思いますが、F#テンプレートでのコンパイル時の導出型の使用
type saveXY<'a when 'a:comparison> (x:'a,y:'a) =
member this.X = x
member this.Y = y
member this.lessThan() = this.X < this.Y
[<EntryPoint>]
let main argv =
let x1 = 3
let y1 = 7
let saver1 = new saveXY<int>(x1,y1) // Good
printfn "%A" (saver1.lessThan())
let x2 = 3.0
let y2 = 7.0
let saver2 = new saveXY<float>(x2,y2) // Good
printfn "%A" (saver2.lessThan())
let saver3 = new saveXY<x2.GetType()> (x2,y2) // No Good, see errors
0
ただし、以下saver3
のために私は(と私はFS1241上の情報を見つけるカント)を取得:
...\Program.fs(23,39): error FS0010: Unexpected symbol '(' in type arguments. Expected ',' or other token.
...\CompareProblem\Program.fs(23,39): error FS1241: Expected type argument or static argument
あなたはsaveXY
上のテンプレートを削除した場合saver1
が012の原因として、そしてsaver2
にエラーがありますクラスの引数はintに制約されます。
私はxとyを単にobj
と宣言して実験しましたが、これはうまくいきません。私は問題がこれは単純に可能ではないということだと思っています。クラス引数の型がジェネリックである場合は、最初に使用されたときに派生したものです。 一方、私は何かを逃しているかもしれません。
F#の型テンプレート引数として、コンパイル時に決定可能な変数ベースの型を使用する方法はありますか?一般的な値を扱う/格納することができる型を作成する別の方法がありますか?
UPDATE:
type saveXY<'a when 'a:comparison> (x:'a, y:'a) =
member this.X = x
member this.Y = y
member this.lessThan() = this.X < this.Y
[<EntryPoint>]
let main argv =
let x1 = 3
let y1 = 7
let saver3 = new saveXY<_> (x1,y1) // works, 'a is int
printfn "%A" (saver3.lessThan())
let x2 = 3.0
let y2 = 7.0
let saver3 = new saveXY<_> (x2,y2) // works, 'a is float
printfn "%A" (saver3.lessThan())
System.Console.ReadKey() |> ignore // wait for a key
0
しかし、なぜ、私はクラス型をテンプレートする必要がある、として:あなたがクラスをテンプレートとそしてちょうどそれが動作するインスタンス化する<_>
を使用する場合リーの提案から、これは、作品私は上記の提案?私が単に(Iは、関数の場合と同じように)使用することはできませんなぜ私はそう<_>
を使用する場合、コンパイラはとにかく種類を推定していることと思われる:
type saveXY(x, y) = // x and y are generic, no? They only require comparison, yes?
member this.X = x
member this.Y = y
member this.lessThan() = this.X < this.Y
[<EntryPoint>]
let main argv =
let x1 = 3
let y1 = 7
let saver3 = new saveXY (x1,y1) // works
printfn "%A" (saver3.lessThan())
let x2 = 3.0
let y2 = 7.0
let saver3 = new saveXY (x2,y2) // But this FAILS with error FS0001
printfn "%A" (saver3.lessThan())
System.Console.ReadKey() |> ignore // wait for a key
0
「x2」と「y2」の型を静的に知っていますが、このような型パラメータを指定することはできません。したがって、ユースケースは明確ではありません。 – Lee
あなたがしようとしていることをあまり明確にはっきりさせていません:コンパイル時には知られていない汎用引数を使ってクラスをインスタンス化するコードを作成しようとしていますか? that_ "を使用して、コンパイラに理解させてもらえますか? –
それは:_simply "どのような型x2が、それを使用してください"と言うと、コンパイラはそれを理解していますか?_ case - 上記の例では、 'saver3'をfloatテンプレート型でインスタンス化したいと思います。 'x2'は浮動小数点です。実際のコードでは、x2はジェネリック型の関数の引数になりますが、関数はさまざまなコンパイル時の型でインスタンス化されます – user1857742