是否可以获取未初始化的案例类的返回类型'方法?我想创建一个像这样工作的包装器:
abstract class Node[L, R]{
def call(args: L): R
}
case class Kls(arg1: Int, arg2: Int) {
def apply() = arg1 + arg2
}
object Node {
def apply[L <: { def apply(): R }, R](implicit lgen: LabelledGeneric[L]): Node[lgen.Repr, R] = {
new Node[lgen.Repr, R] {
def call(args: lgen.Repr): R = {
lgen.from(args).apply()
}
}
}
}
val n = Node[Kls] // does not compile - missing type param R
n.call(arg1 :: arg2 :: HNil) //should have the right return type
或者,是否有FnTo 标记产品?我需要什么样的宏观创造?
答案 0 :(得分:0)
也许我误解了,但我认为你根本不需要L
。
case class Kls(arg1: Int, arg2: Int) {
def apply() = arg1 + arg2
}
abstract class Node[L, R]{
def call(args: L): R
}
import shapeless._
object Node {
def apply[R](implicit gen: LabelledGeneric[R]): Node[gen.Repr, R] =
new Node[gen.Repr, R] {
def call(args: gen.Repr): R = gen.from(args)
}
}
然后:
import shapeless.syntax.singleton._
val n = Node[Kls]
val result = n.call('arg1 ->> 1 :: 'arg2 ->> 2 :: HNil)
将result
静态输入为Kls
的位置。这是你在找什么?
答案 1 :(得分:0)
我用一个简单的宏解决了这个问题:
trait CallApply[C] {
type Ret
def apply(c: C): Ret
}
object CallApply {
type Aux[C, R] = CallApply[C] { type Ret = R }
implicit def materialize[C, R]: Aux[C, R] = macro CallApplyImpl.materialize[C]
}
object CallApplyImpl {
import scala.reflect.macros.whitebox
def materialize[C: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
import c.universe._
val C = weakTypeOf[C]
val assignM = C.decls.collect {
case sym: MethodSymbol if sym.name == TermName("apply") => sym
}
if (assignM.headOption.isEmpty) c.abort(c.enclosingPosition, "case class must define an apply() method")
val R = assignM.head.returnType
q"""new _root_.fwb.api.CallApply[$C] { type Ret = $R; def apply(c: $C) : $R = c.apply() }"""
}
}
用法:
object Node {
def call[L](implicit lgen: LabelledGeneric[L], ev: CallApply[L]): Node[lgen.Repr, ev.Ret] = {
new Node[lgen.Repr, ev.Ret] {
def call(args: lgen.Repr): ev.Ret = {
ev(lgen.from(args))
}
}
}
}
val n = Node[Kls]
按预期工作。然而,如果没有元编程(如果可能的话),那么很高兴看到一个解决方案。