Write me a generic Transformer class with two type parameters K and V, and a dynamic class implementation that maps String keys to Integer values via a transform method.

← Generics · Ref: Q1243

Generic classes can declare multiple type parameters using the syntax 'of type (K, V)' with parameters in parentheses. Both parameters can appear in the abstract method signatures and are independently substituted at the extension site.

GENERIC WITH TWO TYPE PARAMETERS

  Transformer of type (K, V) as abstract
    transform() as abstract
      -> key as K
      <- rtn as V?
    override operator ? as pure
      <- rtn as Boolean: true

The parameter names K and V are conventional but you can use any identifier. The 'of type (K, V)' form is required when there is more than one type parameter.

DYNAMIC CLASS WITH BOTH SUBSTITUTIONS

When extending, supply both concrete types in the same parenthesised form:

  transformer <- () extends Transformer of (String, Integer) as class
    override transform()
      -> key as String
      <- rtn as Integer: length of key

Both parameters are substituted simultaneously: K becomes String and V becomes Integer. The override signature uses the concrete types throughout.

USAGE

  result <- transformer.transform("EK9")
  stdout.println($result)

KEY POINTS

1. Use 'of type (K, V)' with parentheses for multi-parameter generics.
2. Use 'of (Type1, Type2)' at the extension site to supply both.
3. Each type parameter can appear in any position in any method signature.

See Q196 for multi-parameter generics. See Q1234 for single-parameter generic basics. See Q1242 for multi-method generics.

Example

defines module qa.genericsdeep.transformerkv

  defines class

    Transformer of type (K, V) as abstract

      transform() as abstract
        -> key as K
        <- rtn as V?

      override operator ? as pure
        <- rtn as Boolean: true

  defines program

    TransformerKVDemo()
      stdout <- Stdout()

      transformer <- () extends Transformer of (String, Integer) as class
        override transform()
          -> key as String
          <- rtn as Integer: length of key

      result <- transformer.transform("EK9")
      stdout.println($result)

Common mistakes

E50001 — When declaring multiple type parameters, parentheses are required: 'of type (K, V)'. Without parentheses the parser cannot tell where the parameter list ends. See ek9 -h E50001 for details.

Incorrect:

Transformer of type K, V as abstract

Correct:

Transformer of type (K, V) as abstract
Other ways to ask this
  • Create a generic abstract class with two type parameters K and V.
  • Show me how to declare a generic with multiple type parameters in EK9.
  • Implement a Transformer of (K, V) and use it for String to Integer mapping.
  • Build a parameterised type with key and value type parameters.

Coming from another language?

Java: class Transformer<K, V> { abstract V transform(K key); }. Kotlin: abstract class Transformer<K, V> { abstract fun transform(key: K): V }. Scala: trait Transformer[K, V] { def transform(key: K): V }. Rust: trait Transformer<K, V> { fn transform(&self, key: K) -> V }. EK9: 'of type (K, V)' parenthesised form for multi-parameter generics.

Keywords: generic, V, of type, multi parameter, key value, two type parameters, K, Transformer