Get type "singleton type"

We can create literal types using formless ones:

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

But how can I work with Int(42)as a type, even if it is not possible to create an alias of type

type Answ = Int(42) // won't compile
// or
def doSmth(value: Int(42)) = ... // won't compile
+4
source share
2 answers

1) In Typelevel Scala, you can write simply

val x: 42 = 42

type Answ = 42

def doSmth(value: 42) = ???

2) In Dotty Scala you can write the same thing.

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"

4) Typelevel Scala Shapeless.

+6

Int(42) Scala .

IIRC scalac , . Shapeless , , .

, shapeless.Witness - , , .

import shapeless.Witness
import shapeless.syntax.singleton._
import shapeless.test.illTyped // test string for causing type-errors when compiled

// --- Type aliases ---
val w = 42.witness
type Answ1 = w.T // that is your Int(42) singleton type
type Answ2 = Witness.`42`.T // same, but without extra variable
implicitly[Answ1 =:= Answ2] // compiles, types are the same

// --- Value definitions ---
val a: Answ1 = 42 // compiles, value OK, and no need to `narrow`
illTyped { "val b: Answ1 = 43" } // would not compile
val c: Witness.`43`.T = 43 // that syntax is OK here too

// --- Summoning values ---
val answ = Witness[Answ1].value // will not compile for non-singleton
def genericSingletonMethod[A](implicit W: Witness.Aux[A]) = s"Summoning ${W.value}"
assert { genericSingletonMethod[Answ1] == "Summoning 42" }
assert { genericSingletonMethod[Witness.`"string"`.T] == "Summoning string" }
+1

Source: https://habr.com/ru/post/1685546/


All Articles