import c.universe._
import Flag._
def tuple(i: Int) = {
def list = (1 to i).toList
c.typecheck(
ExistentialTypeTree(
tq"(..${list map (i => Ident(TypeName(s"_$i")))})", //just like (_,_, ...)
list map (i =>
TypeDef(Modifiers(DEFERRED | SYNTHETIC), TypeName(s"_$i"), List(), TypeBoundsTree(EmptyTree, EmptyTree))
)
)
)
}
//測試
println(tuple(2).tpe <:< typeOf[(_, _)])//true
println(tuple(3).tpe <:< typeOf[(_, _, _)])//true
EDIT1:
def asTuple(tpe: Type): Boolean = {
def allTuple = 1 to 22 map { i =>
val typeNames = 1 to i map (e => TypeName(s"_$e"))
tq"(..$typeNames) forSome {..${typeNames.map(e => q"type $e")} }"
} map (t => c.typecheck(t).tpe)
allTuple.exists(_ <:< tpe)
}
//測試
println(asTuple(typeOf[Int])) // false
println(asTuple(typeOf[(_, _)])) // true
println(asTuple(typeOf[(_, _,_)])) // true
檢查該名稱是否與'scala.Tuple \ d *'匹配? –
@AlexeyRomanov這是最好的嗎?感覺脆弱但可行。 – flavian
我當然會喜歡它定義'tuple2'等,但我不知道是否有更好的選擇。 –