在下面的代码中,我想使用变量的类型实例化一个模板类,最终作为传递给函数的泛型变量,但即使这个更简单的形式也不起作用:在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
模板,然后saver2
是错误的,因为saver1
导致saveXY
类参数被限制为整数。
我还尝试将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
但为什么我需要模板类的类型,如我上面建议?这似乎是编译器反正演绎的类型,当我使用<_>
那么为什么我不能简单地使用(因为我会为一个函数):
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
不是很清楚你到底想要做什么:你是在试图构建一些代码来实例化你的类,这个类的泛型参数是_is在编译时不知道的,或者你只是想说“_whatever type'x2',请使用that_“,并让编译器找出它? –
它的:_simply想说“任何类型的x2,请使用它”,并让编译器找出它?_ case - 在上面的例子中,我想'saver3'用float模板类型实例化,因为'x2'是一个浮点数。在实际的代码中,x2将是泛型类型的函数参数,但函数实例化的地方是不同的编译时类型 – user1857742