如何收到警告FS1125通用类型'xxx'的实例丢失,并且无法从...推断出来?

问题描述

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>

第二种类型参数'bMake的签名中没有提到,因此它不必匹配任何内容。但是仍然必须以某种方式知道它,因此需要明确指定它。而且,如果未明确指定,则会收到警告。

使用第一个类型参数'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}

但是,当然,如果那样的话,您将无法访问私有构造函数。