agentsclimarketplace

Python scala sealed traits

Skill cxcscmu/SkillLearnBench/skills/b4-skill-creator-claude-sonnet-4-6/python-scala-translation/python-scala-sealed-traits

Guide for translating Python Enum, Protocol, and abstract class hierarchies to Scala sealed trait hierarchies. Use this skill whenever converting Python Enum classes, runtime-checkable Protocol types, abstract base classes (ABC), or Union type aliases to idiomatic Scala sealed traits, case objects, and type classes.From its SKILL.md

Install
npx -y skills add cxcscmu/SkillLearnBench --skill python-scala-sealed-traits

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

SKILL.md

3.8 KB, 850 tokens by cl100k_base, as published. Nobody here has run it

Python Enum → Scala Sealed Trait + Case Objects

Python Enum with string values maps to a sealed trait with case objects in Scala. This provides exhaustive pattern matching and compile-time safety.

Pattern

# Python
class TokenType(Enum):
    STRING = "string"
    NUMERIC = "numeric"
    NULL = "null"
// Scala
sealed trait TokenType { val value: String }
object TokenType {
  case object STRING    extends TokenType { val value = "string"  }
  case object NUMERIC   extends TokenType { val value = "numeric" }
  case object NULL      extends TokenType { val value = "null"    }
}

Why sealed: the compiler enforces exhaustive match expressions, catching missed cases at compile time.

Python Protocol → Scala Trait

Python's @runtime_checkable Protocol (structural typing) translates to a Scala trait. Scala uses nominal (not structural) typing by default, so explicit extends is required.

@runtime_checkable
class Tokenizable(Protocol):
    def to_token(self) -> str: ...
trait Tokenizable {
  def toToken: String   // camelCase per Scala convention
}

Note the naming: Python uses to_token (snake_case); Scala uses toToken (camelCase).

Python ABC → Scala Abstract Class or Trait

class BaseTokenizer(ABC, Generic[T]):
    @abstractmethod
    def tokenize(self, value: T) -> Token: ...

    def tokenize_batch(self, values: Iterable[T]) -> Iterator[Token]:
        for v in values:
            yield self.tokenize(v)
abstract class BaseTokenizer[T] {
  def tokenize(value: T): Token   // abstract — no body

  def tokenizeBatch(values: Iterable[T]): Iterator[Token] =
    values.iterator.map(tokenize)
}

Use an abstract class (not a trait) when the class has constructor parameters. Use a trait for pure interface definitions.

Python Union Type → Scala Overloading or Sealed Trait

Python's Union[datetime, date] can map to method overloading:

class TemporalTokenizer(formatStr: Option[String] = None) {
  def tokenize(value: LocalDateTime): Token = ...
  def tokenize(value: LocalDate): Token = ...
}

Or to a sealed trait if the union is domain-meaningful.

Python Optional[T] / T | None → Scala Option[T]

def tokenize_path(...) -> Token | None: ...
def tokenizePath(...): Option[Token] = ...

Always return Option[T] instead of nullable values. Use Some(x) and None, never null.

Python TypeVar Constraints → Scala Type Bounds

NumericT = TypeVar("NumericT", int, float, Decimal)

In Scala, union-constrained TypeVars are approximated with a common supertype or explicit overloads:

// Overloads for each numeric type:
def tokenize(value: Int): Token    = ...
def tokenize(value: Double): Token = ...
def tokenize(value: BigDecimal): Token = ...

Immutable Data: @dataclass(frozen=True) → case class

@dataclass(frozen=True)
class Token:
    value: str
    token_type: TokenType
    metadata: dict[str, Any] = field(default_factory=dict)
case class Token(
  value:     String,
  tokenType: TokenType,
  metadata:  Map[String, Any] = Map.empty
)

Case classes are immutable by default. copy() creates modified instances.

Python dict[str, Any] → Scala Map[String, Any]

Note: Any in Scala is the top type (similar to Python's Any). Prefer narrower types where possible, but Map[String, Any] is acceptable for flexible metadata.

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.