获取"singleton type"的类型



我们可以通过无形创建字面类型:

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

但是,如果不可能创建类型别名

,我该如何用Int(42)作为一种类型操作
type Answ = Int(42) // won't compile
// or
def doSmth(value: Int(42)) = ... // won't compile
  1. 在Typelevel Scala中您可以写

    val x: 42 = 42
    type Answ = 42
    def doSmth(value: 42) = ???
    
  2. 在Dotty Scala中,您可以写同样的书。

  3. 在LightBend Scala(即标准Scala)中 无形您可以写

    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) = ???
    

在情况1)build.sbt应为

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

在情况2)build.sbt应为

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

和插件.sbt

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

在情况3)build.sbt应为

scalaOrganization := "org.scala-lang"
scalaVersion := "2.12.3"
libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.2"
  1. 或者您可以同时使用Typelevel 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(语言更改/文字类型)

Int(42)不是类型的有效scala语法。

iirc singleton类型在Scalac中实现了一段时间,但是程序员没有定义此类的语法。无形提供了带有宏以及一些额外的机械。

特别是,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" }

最新更新