2017-09-12 56 views
4

我們可以通過無形創建一個文本類型的類型:得到一個「單型」

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 

回答

5

1)Typelevel Scala你可以寫只是

val x: 42 = 42 

type Answ = 42 

def doSmth(value: 42) = ??? 

2)在Dotty的Sca你可以寫同樣的東西。

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" 

和plugins.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" 

4),也可以在同一時間使用Typelevel Scala和無形。

1

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" }