scala - Is it possible to define a macro with variadic parameters, and get a type for each parameter? -


the following obvious variadic function:

def fun(xs: any*) = ??? 

we can define macro in similar way:

def funimpl(c: context)(xs: c.expr[any]*) = ???  fun(1,"1",1.0) 

but in case, arguments typed any. in fact, compiler knows types @ compile-time, hides us. possible list of arguments and types in macro?

sure—for example:

import scala.language.experimental.macros import scala.reflect.macros.context  object demo {   def at(xs: any*)(i: int) = macro at_impl   def at_impl(c: context)(xs: c.expr[any]*)(i: c.expr[int]) = {     import c.universe._      // first let's show can recover types:     println(xs.map(_.actualtype))      i.tree match {       case literal(constant(index: int)) => xs.lift(index).getorelse(         c.abort(c.enclosingposition, "invalid index!")       )       case _ => c.abort(c.enclosingposition, "need literal index!")     }   } } 

and then:

scala> demo.at(1, 'b, "c", 'd')(1) list(int(1), symbol, string("c"), char('d')) res0: symbol = 'b  scala> demo.at(1, 'b, "c", 'd')(2) list(int(1), symbol, string("c"), char('d')) res1: string = c 

note inferred types precise , correct.

note won't work if argument sequence _* type ascription, of course, , you'll need write following if want catch case , provide useful error message:

def at_impl(c: context)(xs: c.expr[any]*)(i: c.expr[int]) = {   import c.universe._    xs.tolist.map(_.tree) match {     case typed(_, ident(tpnme.wildcard_star)) :: nil =>        c.abort(c.enclosingposition, "needs real varargs!")     case _ =>       i.tree match {         case literal(constant(index: int)) => xs.lift(index).getorelse(           c.abort(c.enclosingposition, "invalid index!")         )         case _ => c.abort(c.enclosingposition, "need literal index!")       }   } } 

see question here , bug report here more discussion.


Comments

Popular posts from this blog

Ansible - ERROR! the field 'hosts' is required but was not set -

customize file_field button ruby on rails -

SoapUI on windows 10 - high DPI/4K scaling issue -