Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Pattern Matching pretty printed

Is that possible to somehow marshall PartialFunction (let's assume it will always contains only one case) into something human-readable?

Let's say we have collection of type Any (messages: List[Any]) and number of PartialFuntion[Any, T] defined using pattern matching block.

case object R1
case object R2
case object R3

val pm1: PartialFunction[Any, Any] = {
  case "foo" => R1
}

val pm2: PartialFunction[Any, Any] = {
  case x: Int if x > 10 => R2
}

val pm3: PartialFunction[Any, Any] = {
  case x: Boolean => R3
}

val messages: List[Any] = List("foo", 20)
val functions = List(pm1, pm2)

then we can find all the messages matched by provided PFs and related applications

val found: List[Option[Any]] = functions map { f =>
  messages.find(f.isDefined).map(f)
}

but what if I need resulting map of 'what I expect' to 'what I've got' in the human-readable form (for logging). Say,

(case "foo")         -> Some(R1)
(case Int if _ > 10) -> Some(R2)
(case Boolean)       -> None

Is that possible? Some macro/meta works?

like image 394
Andriy Onyshchuk Avatar asked Jun 24 '15 21:06

Andriy Onyshchuk


1 Answers

There's nothing at runtime which will print compiled code nicely.

You could write a macro which will print the source code of the tree and use that? Most macro tutorials start with a macro for printing source code -- see e.g. http://www.warski.org/blog/2012/12/starting-with-scala-macros-a-short-tutorial/

Perhaps:

// Given a partial function "pf", return the source code for pf
// as a string as well as the compiled, runnable function itself
def functionAndSource(pf: PartialFunction[Any, Any]): (String, PartialFunction[Any, Any]) = macro functionAndSourceImpl

def functionAndSourceImpl ...

val pm1: (String, PartialFunction[Any, Any]) = functionAndSource {
  case "foo" => R1
}

This isn't ever going to be that easy or nice in Scala. Scala isn't Lisp or Ruby: it's a compiled language and it is not optimised for reflection on the code itself.

like image 155
Rich Avatar answered Oct 21 '22 22:10

Rich