cmeeren
cmeeren

Reputation: 4210

Must explicit function type arguments include all generic types in signature?

The following code has signature 'c -> 'c:

let f (x: 'c) = x

However, the following code has signature obj -> obj:

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

Adding the 'c type parameter fixes the signature, reverting it to 'c -> 'c:

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

Is it possible to explicitly declare only some of the signatures? I basically want something along the lines of

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

It's kind of like a deserialization or unboxing, so I need explicit type arguments for 'a, but I really don't care about the type of 'c and would rather not have to explicitly supply it (or a wildcard type).

Upvotes: 0

Views: 79

Answers (1)

kvb
kvb

Reputation: 55184

To directly answer your question, there is no way to include only a subset of the generic parameters in an explicit generic parameter list (<'a,'b,...>), either when defining or when using a function. But it's not clear from your description that this is actually important for your use case.

  1. Just because you explicitly use generic type arguments on a function definition does not mean that you also need to do so when you call the function:

    let f<'a,'c> (x: 'c) = x
    f 1  # works fine with type inference
    
  2. If the return type of f includes 'a in some way in your second case, then type inference will probably also allow you to skip the explicit type parameters even on the definition of f.

However, if 'a doesn't appear anywhere in the signature of f (as part of either an input or output) and it affects behavior in an important way, then it will need to be specified explicitly as a type argument when calling f because there's no way for F#'s type inference to determine what it should be, which will force you to specify the other type arguments too (though possibly as wildcards).

Upvotes: 2

Related Questions