问题描述
Don Syme的this tutorial在这种情况下似乎不适用。
type WrappedFunction<'a,'b> =
private {
Function:'a -> 'b
}
static member Make (f:'a -> int) = {Function = f}
static member Make (f:'a -> string) = {Function = f}
使用时
let a = WrappedFunction.Make (fun (a:DateTime) -> a.ToString())
产生警告。
解决方法
这里缺少见识的地方是:没有规则说Make
静态方法必须返回定义它们的相同类型。
检查一下:
let w : WrappedFunction<int,int> = WrappedFunction<int,bool>.Make (fun i -> string i)
即使我在Make
上调用了WrappedFunction<int,bool>
函数,该方法仍然有效,但是结果的类型为WrappedFunction<int,int>
。
第二种类型参数'b
在Make
的签名中没有提到,因此它不必匹配任何内容。但是仍然必须以某种方式知道它,因此需要明确指定它。而且,如果未明确指定,则会收到警告。
使用第一个类型参数'a
时,情况就不同了:由于Make
的签名中提到了它,因此它必须与周围的类型匹配。因此,例如,这不起作用:
let w = WrappedFunction<string,bool>.Make (fun i -> i + 42)
^^^^^^
|
"The type 'int' does not match the type 'string'"
如果您希望Make
方法在不指定类型参数的情况下“正常工作”,通常的模式是创建一个具有相同名称但没有类型参数的 second 类型,然后将方法放入其中:
type WrappedFunction<'a,'b> =
{
Function:'a -> 'b
}
type WrappedFunction =
static member public Make (f:'a -> int) = {Function = f}
static member public Make (f:'a -> string) = {Function = f}
但是,当然,如果那样的话,您将无法访问私有构造函数。