Generics 使用显式指定的泛型参数推断泛型约束
考虑以下代码:Generics 使用显式指定的泛型参数推断泛型约束,generics,f#,type-inference,Generics,F#,Type Inference,考虑以下代码: let f<'a when 'a:comparison> (x: 'a) = () let g x = f x let h<'b> (x: 'b) = f x 有没有让编译器为我推断约束的技巧?从第二组函数中删除g,然后h生成警告: 此构造导致代码不像 类型注释。类型变量“a”已被约束为类型变量 “System.IComparable” 因此,g中的错误似乎阻止了对h从第二组函数中删除g,并且h生成警告: 此构造导致代码不像 类型注释。类型变量“a”已被
let f<'a when 'a:comparison> (x: 'a) = ()
let g x = f x
let h<'b> (x: 'b) = f x
有没有让编译器为我推断约束的技巧?从第二组函数中删除
g
,然后h
生成警告:
此构造导致代码不像
类型注释。类型变量“a”已被约束为类型变量
“System.IComparable”
因此,
g
中的错误似乎阻止了对h
从第二组函数中删除g
,并且h
生成警告:
此构造导致代码不像
类型注释。类型变量“a”已被约束为类型变量
“System.IComparable”
因此,
g
中的错误似乎阻止了对h
进行完整的类型检查,只要您只在参数和/或返回类型之后注释类型参数,而不是函数名,类型推断似乎就可以工作
按照您的第一个示例进行操作:
let f<'a when 'a:comparison> (x: 'a) = ()
let i (x: 'b) = f x
// val i : x:'b -> unit when 'b : comparison
您应该能够以这种方式编写代码,因为在函数名中指定类型参数是不必要的
即使多次使用受约束类型,也只需第一次对其进行描述:
let l (x: 'e when 'e:unmanaged) (y : 'e) = f x
// val l : x:'e -> y:'e -> unit when 'e : unmanaged and 'e : comparison
所有相同的技巧都适用于返回类型:
let f'<'a when 'a:comparison> () = (new obj ()) :?> 'a
let g' () : 'b when 'b : unmanaged = f' ()
// val g' : unit -> 'b when 'b : unmanaged and 'b : comparison
让f'()=(新的obj()):?>'a
当'b:unmanaged=f'()
//val g':当“b:非托管”和“b:比较”时,单元->“b”
因此,唯一剩下的痛点是一个既没有泛型输入参数也没有泛型返回类型的泛型函数 只要您只在参数和/或返回类型之后注释类型参数,而不是在函数名之后注释,类型推断似乎就可以工作 按照您的第一个示例进行操作:
let f<'a when 'a:comparison> (x: 'a) = ()
let i (x: 'b) = f x
// val i : x:'b -> unit when 'b : comparison
您应该能够以这种方式编写代码,因为在函数名中指定类型参数是不必要的
即使多次使用受约束类型,也只需第一次对其进行描述:
let l (x: 'e when 'e:unmanaged) (y : 'e) = f x
// val l : x:'e -> y:'e -> unit when 'e : unmanaged and 'e : comparison
所有相同的技巧都适用于返回类型:
let f'<'a when 'a:comparison> () = (new obj ()) :?> 'a
let g' () : 'b when 'b : unmanaged = f' ()
// val g' : unit -> 'b when 'b : unmanaged and 'b : comparison
让f'()=(新的obj()):?>'a
当'b:unmanaged=f'()
//val g':当“b:非托管”和“b:比较”时,单元->“b”
因此,唯一剩下的痛点是一个既没有泛型输入参数也没有泛型返回类型的泛型函数 我不认为有什么技巧可以使用-理想情况下,您不需要显式地设置函数的类型参数,因为编译器应该能够找出它们-或者您有什么理由需要它们吗?编译器只能找出在参数或结果中使用的类型。我需要一个作用于类型而不是值的函数。这是与静态约束一起使用的,类似于一般零的工作原理。我不认为有什么技巧可以使用-理想情况下,您不需要将函数的类型参数显式化,因为编译器应该能够找出它们——或者您有什么理由需要它们吗?编译器只能找出在参数或结果中使用的类型。我需要一个作用于类型而不是值的函数。这与静态约束一起使用,类似于泛型零的工作方式。这对没有参数的函数没有帮助,请参见问题的后半部分。对没有参数的函数没有帮助,请参见问题的后半部分。即使我删除了
g
,h
,也不会是泛型的。我们的目标是以后像let x=h()
那样使用它。不,h
仍然不是通用的,但是删除g
可以揭示真正的行为。我只是指出类型参数并没有被完全忽略。即使我删除了g
,h
,它仍然不是泛型的。我们的目标是以后像let x=h()
那样使用它。不,h
仍然不是通用的,但是删除g
可以揭示真正的行为。我只是指出类型参数并没有被完全忽略。