Generics 显式函数类型参数必须包含签名中的所有泛型类型吗?

Generics 显式函数类型参数必须包含签名中的所有泛型类型吗?,generics,f#,Generics,F#,以下代码具有签名'c->'c: let f (x: 'c) = x let f<'a, 'c> (x: 'c) = x 但是,以下代码具有签名obj->obj: let f<'a> (x: 'c) = x 是否可以只显式声明部分签名?我基本上想要的是类似于 let f<'a> (x: MyType<'c>) = let foo = doSomethingBasedOn typeof<'a> processXWithoutC

以下代码具有签名
'c->'c

let f (x: 'c) = x
let f<'a, 'c> (x: 'c) = x
但是,以下代码具有签名
obj->obj

let f<'a> (x: 'c) = x
是否可以只显式声明部分签名?我基本上想要的是类似于

let f<'a> (x: MyType<'c>) =
  let foo = doSomethingBasedOn typeof<'a>
  processXWithoutCaringAboutTypeC x foo
let f)=

让foo=doSomethingBasedOn typeof直接回答您的问题,无论是在定义函数还是在使用函数时,都无法在显式泛型参数列表(
)中仅包含泛型参数的子集。但是,从您的描述中不清楚这对您的用例实际上是重要的

  • 仅因为在函数定义上显式使用泛型类型参数,并不意味着您在调用函数时也需要这样做:

    let f<'a,'c> (x: 'c) = x
    f 1  # works fine with type inference
    
    设f(x:'c)=x
    F1#适用于类型推断
    
  • 如果在第二种情况下,
    f
    的返回类型以某种方式包括
    'a
    ,则类型推断可能还允许您跳过显式类型参数,即使在
    f
    的定义上也是如此


  • 但是,如果
    'a
    没有出现在
    f
    的签名中的任何地方(作为输入或输出的一部分),并且它以一种重要的方式影响行为,那么在调用
    f
    时,需要将其显式指定为类型参数,因为f#的类型推断无法确定它应该是什么,这将迫使您也指定其他类型参数(尽管可能是通配符)。

    要直接回答您的问题,无论是在定义还是在使用函数时,都无法在显式泛型参数列表(
    )中仅包含泛型参数的子集。但是,从您的描述中不清楚这对您的用例实际上是重要的

  • 仅因为在函数定义上显式使用泛型类型参数,并不意味着您在调用函数时也需要这样做:

    let f<'a,'c> (x: 'c) = x
    f 1  # works fine with type inference
    
    设f(x:'c)=x
    F1#适用于类型推断
    
  • 如果在第二种情况下,
    f
    的返回类型以某种方式包括
    'a
    ,则类型推断可能还允许您跳过显式类型参数,即使在
    f
    的定义上也是如此


  • 但是,如果
    'a
    没有出现在
    f
    的签名中的任何地方(作为输入或输出的一部分),并且它以一种重要的方式影响行为,那么在调用
    f
    时,需要将其显式指定为类型参数,因为f#的类型推断无法确定它应该是什么,这将迫使您也指定其他类型参数(尽管可能是通配符)。

    我想问题是,在您的上一个示例中,
    processxwithout-caringabouttypec
    需要知道类型
    'c
    ,希望它是一个类型参数(通常由编译器推断)。我怀疑你能做得比《代码》更好,你确定这不会把‘c’约束到obj吗?(现在不在计算机前)你说的“那”是什么意思?
    让我们来看一下,我怀疑你的函数
    processxwithout caringabouttypec
    根本不接受类型参数。你能显示它的签名吗?我想问题是,在上一个示例中,
    processxwithout caringabouttypec
    需要知道类型
    'c
    ,希望它是一个类型参数(通常由编译器推断)。我怀疑你能做得比《代码》更好,你确定这不会把‘c’约束到obj吗?(现在不在计算机前)你说的“那”是什么意思?
    让我们来看一下,我怀疑你的函数
    processxwithout caringabouttypec
    根本不接受类型参数。你能出示它的签名吗?谢谢。不幸的是,这确实是你的观点
    MyType
    包含类型
    系统的成员。type
    ,而
    'a
    用于与此类型进行比较。
    MyType
    的类型参数与该特定比较无关。因此,我必须在调用时明确指定
    'a
    。在这种情况下,您可以只接收
    System.type
    类型的参数
    ta
    ,并对其进行所需的比较,而不是使用泛型参数
    'a
    。如果您将
    ta
    作为第一个参数传递,那么您甚至可以使用部分应用程序。是的,事实上,我刚刚开始尝试这一点。:)谢谢谢谢不幸的是,这确实是你的观点
    MyType
    包含类型
    系统的成员。type
    ,而
    'a
    用于与此类型进行比较。
    MyType
    的类型参数与该特定比较无关。因此,我必须在调用时明确指定
    'a
    。在这种情况下,您可以只接收
    System.type
    类型的参数
    ta
    ,并对其进行所需的比较,而不是使用泛型参数
    'a
    。如果您将
    ta
    作为第一个参数传递,那么您甚至可以使用部分应用程序。是的,事实上,我刚刚开始尝试这一点。:)谢谢