Неявный classTag и карри - PullRequest
       16

Неявный classTag и карри

0 голосов
/ 13 апреля 2019

Я пытаюсь написать функцию, которая возвращает 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 имеется несоответствие типов (он ожидает * 1015)* за C я думаю).Есть ли способ иметь его в обе стороны, иметь ClassTag и fun?

1 Ответ

1 голос
/ 13 апреля 2019

Вы можете написать это как

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

или (хуже)

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

(где implicitly может указывать тип: implicitly[ClassTag[Config]] или может быть заменен на classTag).

...