agentsclimarketplace

Scala generics

Skill cxcscmu/SkillLearnBench/skills/b1-one-shot-claude-haiku-4-5/python-scala-translation/scala-generics

Translating Python generic types, variance, and type bounds to Scala 2.13From its SKILL.md

Install
npx -y skills add cxcscmu/SkillLearnBench --skill scala-generics

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

3.5 KB, ~1.0k tokens by cl100k_base, as published. Nobody here has run it

Scala Generics and Type System for Python Developers

Core Concepts

Variance (Key Difference from Python)

Python has no explicit variance system. Scala requires explicit declarations:

Covariance (+T) - "out" position, can return subtypes:

class Container[+T](items: Seq[T]) {
  def get: T = items.head  // OK - returning subtype
  // def set(t: T): Unit   // ERROR - would be contravariant
}

Contravariance (-T) - "in" position, can accept supertypes:

class Consumer[-T] {
  def consume(t: T): Unit  // OK - accepting supertype
  // def produce: T         // ERROR - would be covariant
}

Invariance (T) - exact type, no variance:

class Handler[T] {
  def get: T
  def set(t: T): Unit  // Both OK - invariant
}

Translation Pattern

PythonScalaNotes
TypeVar("T")[T]Invariant by default
TypeVar("T_co", covariant=True)[+T]Covariant, out-position only
TypeVar("T_contra", contravariant=True)[-T]Contravariant, in-position only
TypeVar("T", int, float)[T <: Int | Float]Upper bound (Scala 3) or sealed trait
Generic[T][T]Class definition
Union[A, B]A | B (Scala 3) or sealed traitUse sealed traits for compatibility

Type Bounds

// Upper bound - T must be subtype of Ordered
class Comparable[T <: Ordered[T]]

// Lower bound - T must be supertype of String
class Container[T >: String]

// Context bound (implicit evidence)
class Serializable[T: Format]

Higher-Kinded Types (Scala's advantage)

Python's TypeVar("F") for type constructors cannot express true HKTs. Scala can use type lambdas:

// Scala 2.13 with kind-projector
type Functor[F[_]] = {
  def map[A, B](fa: F[A], f: A => B): F[B]
}

// Or in Scala 3
def map[F[_], A, B](fa: F[A], f: A => B): F[B]

Translation Examples

Generic Container (Python)

class TokenContainer(Generic[T_co]):
    def __init__(self, items: Sequence[T_co]) -> None:
        self._items: tuple[T_co, ...] = tuple(items)

    def get_all(self) -> tuple[T_co, ...]:
        return self._items

Generic Container (Scala 2.13)

class TokenContainer[+T](items: Seq[T]) {
  private val _items: Vector[T] = items.toVector

  def getAll: Vector[T] = _items
  def size: Int = _items.size
}

Collections Generics

Python uses Sequence[T], Iterable[T], etc. Scala equivalents:

PythonScala
Sequence[T]Seq[T] (immutable)
Iterable[T]Iterable[T]
Iterator[T]Iterator[T]
list[T]scala.collection.mutable.ListBuffer[T] or List[T] (immutable)
tuple[T, ...]Vector[T] or (T, T, ...) for fixed size
dict[K, V]Map[K, V]

Best Practices for Scala 2.13

  1. Prefer immutable by default - use Vector, List, Map
  2. Generics in method position - use [T] not just at class level
  3. Variance where appropriate - adds flexibility but keep simple
  4. Use sealed traits for union types - more powerful than Python's Union
  5. Type classes for ad-hoc polymorphism - replaces duck typing

Working with Circe JSON Types

Circe provides Json type which is immutable and generic:

import io.circe._

// Json is essentially: Json = JNull | JBoolean | JNumber | JString | JArray | JObject
val json: Json = Json.fromString("hello")
val jsonObj: Json = Json.obj("key" -> Json.fromString("value"))

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.