隐含的classTag和currying

问题描述 投票:0回答:1

我正在尝试编写一个函数,它返回一个没有最后一个参数的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):编译器告诉我在fun上存在类型不匹配(我认为ClassTagC)。有没有办法让它有两种方式,有一个ClassTagfun

scala implicit
1个回答
1
投票

你可以把它写成

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

或者(更糟)

foldArgs[Config](args)(implicitly)(fun)

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

© www.soinside.com 2019 - 2024. All rights reserved.