显式函数类型参数必须在签名中包括所有泛型类型吗?

时间:2019-03-20 14:55:57

标签: generics f#

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

let f (x: 'c) = x

但是,以下代码具有签名obj -> obj

let f<'a> (x: 'c) = x

添加'c类型的参数可修复签名,并将其还原为'c -> 'c

let f<'a, 'c> (x: 'c) = x

是否可以仅声明某些签名?我基本上想要一些类似的东西

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

有点像反序列化或拆箱,所以我需要为'a使用显式类型参数,但是我真的不在乎'c的类型,宁愿不必显式提供它(或通配符类型)。

1 个答案:

答案 0 :(得分:2)

要直接回答您的问题,无论是在定义还是使用函数时,都无法在显式通用参数列表(<'a,'b,...>)中仅包括通用参数的子集。但是从您的描述中尚不清楚这对于您的用例实际上是否重要。

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

    let f<'a,'c> (x: 'c) = x
    f 1  # works fine with type inference
    
  2. 如果在第二种情况下,f的返回类型在某种程度上包含'a,则即使在{的定义下,类型推断也可能使您跳过显式类型参数{1}}。

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