You required: a) write new Foo[T]()instead of new Foo[Any]()(easy) b) transfer to the macro view of a type T, namely the type of value AbsTypeTag[T], declaring a parameter Tvia binding to the context: [T: c.AbsTypeTag].
, Scala 2.10.0-M7. Edit. 2.10.0-RC1 AbsTypeTag WeakTypeTag. .
Creator.scala:
import language.experimental.macros
import reflect.macros.Context
class Foo[T]
object Creator {
def create[T](s: String): Foo[T] = macro createImpl[T]
def createImpl[T: c.AbsTypeTag](c: Context)(s: c.Expr[String]): c.Expr[Foo[T]] = {
import c.universe._
reify(new Foo[T]())
}
}
MacroClient.scala:
object Main extends App {
println (Creator.create[Int](""))
}
, , :
scala> Creator.create[Int]("")
res2: Foo[Int] = Foo@4888884e
scala> Creator.create("")
<console>:12: error: macro has not been expanded
Creator.create("")
^
:
( , T [T, Unit])
, . Creator.create[T](otherArgs) - Creator.create(T, otherArgs), ( ). : class A object A , : A, A.type, A , A.
: Creator create Foo Foo, Foo.
Any reify, , . , , Creator.create T, Any; .
. Creator create Foo Foo Creator.create, , Foo.type, Foo . Scala - , . , , .
trait Companion[Class]
class Foo
object Foo extends Companion[Foo]
object Bar extends Companion[Foo]
object pInt extends Companion[Int]
object Creator {
def create[S, T <: Companion[S]](obj: T with Companion[S]): S = ???
}
, -, , . ( S create) - , , .
, , :
import language.experimental.macros
import reflect.macros.Context
class Foo[T]
object Creator {
//T with Companion[S] is needed to workaround a type inference bug (SI-5298) and allow S to be correctly inferred.
def create[S, T <: Companion[S]](obj: T with Companion[S]): Foo[S] = macro createImpl[S, T]
def createImpl[S: c.AbsTypeTag, T <: Companion[S]: c.AbsTypeTag](c: Context)(obj: c.Expr[T with Companion[S]]): c.Expr[Foo[S]] = {
import c.universe._
reify(new Foo[S]())
}
}