Search code examples
scalasingleton-type

Get instance of singleton type in scala


I want to get the instance of a singleton type in Scala, is this possible?

Example: (I know it can be done easier in this case)

sealed trait Animal
case object Dog extends Animal
case object Cat extends Animal

trait Person {
  def name: String
  // Is there a "FavoriteAnimal.instance" syntax?
  def mostImportantThings = (FavoriteAnimal.instance, name)
  protected type FavoriteAnimal <: Animal with scala.Singleton
}

case class DogPerson(override val name: String) extends Person {
  override type FavoriteAnimal = Dog.type
}

case class CatPerson(override val name: String) extends Person {
  override type FavoriteAnimal = Cat.type
}

Solution

  • Using shapeless.Witness correct syntax is

    sealed trait Animal
    case object Dog extends Animal
    case object Cat extends Animal
    
    trait Person {
      def name: String
      def mostImportantThings(implicit 
        witness: Witness.Aux[FavoriteAnimal]
      ): (FavoriteAnimal, String) = (witness.value, name)
      protected type FavoriteAnimal <: Animal with scala.Singleton
    }
    
    case class DogPerson(override val name: String) extends Person {
      override type FavoriteAnimal = Dog.type
    }
    
    case class CatPerson(override val name: String) extends Person {
      override type FavoriteAnimal = Cat.type
    }
    
    DogPerson("A Dog Person").mostImportantThings // (Dog, A Dog Person)
    

    Unfortunately in the current version of Shapeless (2.3.3) there is a bug and this code doesn't compile. But after fix it does.