[SOLVED] Scala 3 enum: case with body

Let my code be:

trait Error:
  def message: String

sealed trait AssetError extends Error

enum NamespaceError extends AssetError:
  case BlankInput

  case InvalidCharacter(input: String, char: Char)
    extends NamespaceError:
      override def message: String = s"...$input ... $char"
  
  case Other(override val message: String)
  
  override def message: String = productPrefix

Doing this, I get the following error:

end of statement expected but ‘:’ found (bloop)

I thought this was the way to implement a body for a enum case but apparently I am doing something wrong.

Am I complete wrong with my assumption or is there just a small error?

Enums don’t let you do that, it’s an intentional restriction:


This is from Programming in Scala 5th Edition.

If you want a subclass body, then you need to fall back to the usual sealed trait pattern explicitly.

4 Likes

Thank you so much for your help.

1 Like

Also note that you can always do the “dynamic dispatch” manually:

trait Error:
  def message: String

sealed trait AssetError extends Error

enum NamespaceError extends AssetError:
  case BlankInput

  case InvalidCharacter(input: String, char: Char)
  
  case Other(override val message: String)
  
  override def message: String = this match
    case BlankInput => ""
    case InvalidCharacter(input, char) => s"...$input ... $char"
    case Other(message) => message

(I wasn’t sure what you wanted to do with productPrefix, so I omited it)

P.S:
It turns out you can override the enum methods with case vals however !

trait Error:
  def message: String

sealed trait AssetError extends Error

enum NamespaceError extends AssetError:
  case BlankInput

  case InvalidCharacter(input: String, char: Char)
  
  case Other(override val message: String)
  
  override def message: String = "hello"


NamespaceError.Other("test").message // "test": String


(NamespaceError.Other("test"): Error).message // "test": String
3 Likes