E06021: a generic function infers its type arguments only when its parameters are exactly its type parameters, in order; parameterise it explicitly
What went wrong
A call to a generic function tried to infer its type arguments from its arguments, but the function is not in the one shape that can be inferred. A generic function infers its type arguments ONLY when its parameters are exactly its type parameters, in order, and nothing else - then argument 1's type is type argument 1, and so on. Any other shape - a parameter of 'List of T', a 'T' beside an 'Integer', 'T' twice, no 'T' at all, or the type parameters in a different order - says nothing reliable about what 'T' is, so EK9 does not guess.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 681 (What is the correct syntax for generic type parameterization...)
- ek9 -q 58 (How do generic functions work in EK9?)
How to fix it
- Parameterise the function explicitly and call the result:
counter <- countOf() of String stdout.println($counter(names))
- Or, where the function is yours, give it the inferring shape: its parameters exactly its type parameters, in order ('-> item as T').
Infers
identity() of type T -> item as T identity(42) pair() of type (K, V) -> key as K, amount as V pair("a", 1)
[DOES NOT INFER - write 'f() of X']
countOf() of type T -> items as List of T tag() of type T -> item as T, count as Integer findMax() of type T -> first as T, second as T repeat() of type T -> count as Integer pick() of type (A, B) -> second as B, first as A
Rationale
This is the same rule as a generic class's inferring constructor (E06050): one shape, where the arguments ARE the type arguments. There is no unification - reading an argument's type as a type argument in any other shape type-checks the wrong thing.
Common causes
- Expecting 'T' to be worked out from 'List of T' (as Java or Kotlin do)
- A generic function with an extra non-generic parameter
- Calling a function that takes two values of one 'T'
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E06021: a generic function infers its type arguments only when its parameters are exactly its type parameters, in order; parameterise it explicitly
#!ek9 defines module error.e06021.bad defines function countOf() of type T -> items as List of T <- rtn as Integer: length items tag() of type T -> item as T count as Integer <- rtn as String: `${item}:${count}` defines program Inference() names <- ["a", "b"] //'T' sits inside 'List of T': the parameters are not exactly the type parameters howMany <- countOf(names) //A 'T' and an 'Integer': two arguments, one type parameter tagged <- tag("x", 3)
Fixed: Parameterise the generic function explicitly - 'countOf() of String' - and call the result
#!ek9 defines module error.e06021.good defines function countOf() of type T -> items as List of T <- rtn as Integer: length items tag() of type T -> item as T count as Integer <- rtn as String: `${item}:${count}` defines program Inference() stdout <- Stdout() names <- ["a", "b"] counter <- countOf() of String stdout.println($counter(names)) tagger <- tag() of String stdout.println(tagger("x", 3))