Scala: Dynamically generating match clauses for case classes -


i want use power of scala's pattern matching within set of `condition-action' rules. these rules not known in advance, rather generated @ runtime according complex critera. algorithmic generation mechanism can considered separate , not part of question, concerned how express via scala reflection/quasiquotes.

concretely, i'm looking generate case definitions (of general form case v0@x(v1,_,v2): x => f(v1,v2)) @ runtime.

it presumably possible via toolbox.parse(str) string generated @ runtime. however, if possible seem desirable incorporate greater degree of type-safety this:

more specifically, want case defs match against sealed case class hierarchy of terms (term,var(name: char),lit(value:int),group(a: term,b: term,c: term)).

for example, generated case def in general, return function of none, or of v0,v1,v2:

  t match {     case v0@group(v1@_,v2@var('a')) => group(v2,v0,group(v1,var('z'),lit(17))) // etc   } 

i'm attempting follow through on description of quasiquotes case defs given here, syntax rather mind-bending (and eclipse scala 2.11 refuses show me types), below far i've got. specific questions embedded in code:

def dynamicmatch(condition: sometype, action: sometype, tb: toolbox) (t: term): option[term] = {    // q1. type should condition , action maximum   // typesafety in calling code? symbols? quasiquotes?    // best combined single actual casedef?    // hardcoded placeholder expression, in general:   // q2. how bind in t, condition , action?   val q"$expr match { case ..$cases }" =     q"foo match { case _ : term => some(expr) case _ => none }"    val cq"$pat1 => $body1" :: cq"$pat2 => $body2" :: nil = cases    // q3. how should invoked return desired result?   ??? } 

there's shapeless example builds function invocation purpose of getting toolbox select typeclass based on runtime types.

you want build logic dynamically, you're having difficulty quasiquoting.

this something:

// classes sealed trait term case class lit(value: int) extends term case class group(a: term, b: term) extends term  // build function hooks patterns other expressions   def stagedtermfunction(t: term): option[term] = {     // add lits     val tt = tq"_root_.shapeless.examples.term"     val lit = q"_root_.shapeless.examples.lit"     val grp = q"_root_.shapeless.examples.group"     val pat = pq"$grp($lit(x), $lit(y))"     val add = cq"$pat => some($lit(x + y))"     val default = cq"_ => none"     val cases = add :: default :: nil     val res = q"{ case ..$cases } : (($tt) => option[$tt])"     val f = evaltree[term => option[term]](res)     f(t)   } 

then doesn't blow up:

  val t3: term = group(lit(17), lit(42))   val some(lit(59)) = stagedtermfunction(t3)   assert(stagedtermfunction(lit(0)) == none) 

if wanted manipulate symbolof[group] might have convert sym.fullname select tree built q"name"; think there's utility method somewhere.


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

css - Make div keyboard-scrollable in jQuery Mobile? -

ruby on rails - Seeing duplicate requests handled with Unicorn -