How do I define generics with multiple type parameters in EK9?

← Generics · Ref: Q196

EK9 supports multiple type parameters using parentheses: 'of type (A, B)'. This enables types like Pair, Either, and mapper functions with distinct input/output types.

MULTIPLE TYPE PARAMETERS

Use parentheses for multiple parameters:

  Pair of type (A, B)
    first as A?
    second as B?

INSTANTIATION

Provide both types explicitly:

  pair <- Pair("hello", 42) of (String, Integer)

Or let EK9 infer them:

  pair <- Pair("hello", 42)

GENERIC FUNCTIONS WITH MULTIPLE PARAMETERS

Functions can also use multiple type parameters:

  mapper() of type (S, T) as open
    -> source as S
    <- target as T?

BUILT-IN EXAMPLES

Dict, Result, and DictEntry all use multiple type parameters:

  Dict of (String, Integer)
  Result of (String, Integer)

See Q194 for single-parameter generics. See Q195 for constraints. See Q46 for Dict.

See Q654 for parameter count validation. See Q655 for method overloading with generics.

Example

defines module qa.generics.multitype

  defines class

    Pair of type (A, B)
      first as A?
      second as B?

      Pair() as pure
        first :=? A()
        second :=? B()

      Pair() as pure
        ->
          a as A
          b as B
        first :=? a
        second :=? b

      getFirst()
        <- rtn as A: A()
        rtn :=? A(first)

      getSecond()
        <- rtn as B: B()
        rtn :=? B(second)

      default operator ?

  defines program

    MultiParamGenericDemo()
      stdout <- Stdout()

      // === INSTANTIATION WITH INFERENCE ===

      pair <- Pair("hello", 42)
      stdout.println(`Pair is set: ${pair?}`)

      // === ACCESSING VALUES ===

      first <- pair.getFirst()
      if first?
        stdout.println(`First: ${first}`)

      second <- pair.getSecond()
      if second?
        stdout.println(`Second: ${second}`)

      // === DIFFERENT TYPE COMBINATIONS ===

      boolFloat <- Pair(true, 3.14)
      stdout.println(`Bool-Float pair set: ${boolFloat?}`)

Common mistakes

E06220 — Pair requires two type parameters (A, B). Providing only one type argument does not match the generic definition. See ek9 -h E06220 for details.

Incorrect:

pair <- Pair("hello") of String

Correct:

pair <- Pair("hello", 42)

E06030 — A generic class constructor parameter count must match the number of type parameters. Pair of type (A, B) needs a constructor accepting both A and B. See ek9 -h E06030 for details.

Incorrect:

a as A

Correct:

a as A
          b as B
Other ways to ask this
  • Can EK9 generics have more than one type parameter?
  • How do I create a Pair type with two generic parameters?
  • What is the syntax for multi-parameter generics in EK9?

Coming from another language?

Java: class Pair<A, B> with angle brackets. C++: template<typename A, typename B>. Rust: struct Pair<A, B>. Go: type Pair[A, B any]. Kotlin: class Pair<A, B>. EK9: 'Pair of type (A, B)' with parentheses for multiple parameters, reads as natural English.

Keywords: tuple, define, type-parameter, multi, generic, type, parameterized, parentheses, pair, multiple, parameter