隐式classTag和currying

时间:2019-04-12 21:42:14

标签: scala implicit

我正在尝试编写一个返回foldLeft且不带最后一个参数的函数,我也需要将其参数化。我需要为此参数使用ClassTag,但是似乎无法同时拥有implicit ClassTag和为实现功能的范围留出空间:

def fields[T](implicit ctag: ClassTag[T]) : Array[String] =
  ctag.runtimeClass.getDeclaredFields.map(_.getName)

def foldArgs[C](args: Array[String])(implicit ctag: ClassTag[C])
  : ((C, (String, String)) => C) => C = {
   val tt = weakTypeTag[C].tpe
   val clsMirror = universe
     .runtimeMirror(getClass.getClassLoader)
     .reflectClass(tt.typeSymbol.asClass)
   val ctorSym = tt.decl(universe.termNames.CONSTRUCTOR).asMethod
   val instance = clsMirror.reflectConstructor(ctorSym)().asInstanceOf[C]
   fields[C].zip(args).foldLeft(instance)
}

case class Config(a: Int, b: Double, c: String)

def fun: (Config, (String, String)) => Config = ???

def main(args: Array[String]): Unit = {
  Try { foldArgs[Config](args)(fun) } match {
    case Success(a) => println(a)
    case Failure(e) => println(s"${e.getMessage}")
  }
}

foldArgs中的最后一行需要将ClassTag[C]传递给fields,但是如何创建ClassTag[C]?看来我必须依次将其作为implicit传递给foldArgs本身,这现在中断了调用foldArgs[Config](args)(fun):编译器告诉我{{1 }}(我认为fun会使用ClassTag)。有没有办法同时拥有CClassTag

1 个答案:

答案 0 :(得分:1)

您可以将其写为

resolve_redirects

或(更糟)

foldArgs[Config](args).apply(fun)

(其中foldArgs[Config](args)(implicitly)(fun) 可以指定类型:implicitly,或者可以用implicitly[ClassTag[Config]]代替)。