Search code examples
scalageneric-programmingshapeless

Get type of a "singleton type"


We can create a literal types via shapeless:

import shapeless.syntax.singleton._
var x = 42.narrow
// x: Int(42) = 42

But how can I operate with Int(42) as a type if it's even impossible to create type alias

type Answ = Int(42) // won't compile
// or
def doSmth(value: Int(42)) = ... // won't compile

Solution

    1. In Typelevel Scala you can write just

      val x: 42 = 42
      
      type Answ = 42
      
      def doSmth(value: 42) = ???
      
    2. In Dotty Scala you can write the same.

    3. In Lightbend Scala (i.e. standard Scala) + Shapeless you can write

      import shapeless.Witness
      import shapeless.syntax.singleton._
      
      val x: Witness.`42`.T = 42.narrow
      
      type Answ = Witness.`42`.T
      
      def doSmth(value: Witness.`42`.T) = ???
      

    In case 1) build.sbt should be

    scalaOrganization := "org.typelevel"
    scalaVersion := "2.12.3-bin-typelevel-4"
    scalacOptions += "-Yliteral-types"
    

    In case 2) build.sbt should be

    scalaOrganization := "ch.epfl.lamp"
    scalaVersion := "0.3.0-RC2"
    

    and plugins.sbt

    addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.1.5")
    

    In case 3) build.sbt should be

    scalaOrganization := "org.scala-lang"
    scalaVersion := "2.12.3"
    libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.2"
    
    1. or you can use Typelevel Scala and Shapeless at the same time.

    Update. Since version 2.13.0 there are literal types in standard Scala

    val x: 42 = 42
    val x1: 42 = valueOf[42]
    
    type Answ = 42
    
    def doSmth(value: 42) = ???
    

    https://github.com/scala/scala/releases/v2.13.0 (Language changes / Literal types)