考虑以下代码:
let f<'a when 'a:comparison> (x: 'a) = ()
let g x = f x
let h<'b> (x: 'b) = f x
函数 f
具有通过比较约束的通用参数 .
在函数 g
中,我只使用 f
并让编译器推断它正确执行的泛型参数,从而产生 g: 'a -> unit when 'a : comparison
.
但是,如果我需要显式指定泛型参数,如函数 h
,编译器由于某种原因无法推断约束,导致 x
下的红色波浪形,说“类型参数缺少约束'when ' b:比较' . ”
这对于没有非泛型参数的函数尤其令人讨厌,即 let f<'a> = ()
,或者其非泛型参数没有提及泛型类型,即 let f<'a> () = ()
,因为我每次使用时都必须指定约束 . 函数在另一个泛型函数中:
let f<'a when 'a:comparison> () = ()
let g<'a> () = f<'a> () // Error: A type parameter is missing a constraint
let h () = f<'a> () // h gets inferred as unit -> unit, losing generic parameter
let k<'a when 'a:comparison> () = f<'a> () // The only working way
是否有一个技巧让编译器为我推断约束?
2 回答
从第二组函数中删除
g
,h
生成警告:所以,似乎
g
中的错误阻止了h
的完整类型检查 .只要您只在参数和/或返回类型之后注释类型参数,而不是函数名称,类型推断似乎有效 .
从你的第一个例子开始:
如果参数本身具有泛型类型和/或其他类型约束,它也可以工作:
你应该能够以这种方式编写代码,因为在函数名中指定type参数是不必要的 .
即使您不止一次使用约束类型,您也只需要在第一次描述它:
所有相同的技巧都适用于返回类型:
因此,唯一的痛点是泛型函数既没有通用输入参数也没有泛型返回类型 .