scala - Why implicit conversion of a code block does not work -


could please explain why second call listen method not work , suggest solution make work?

object example extends app {   case class event(kind: int)   trait listener { def handle(e: event) }   val listeners = scala.collection.mutable.map[int, listener]()   def emit(e: event) = listeners.get(e.kind).foreach(_.handle(e))   def listen(kind: int)(f: (event) => unit) {     val l = new listener() { override def handle(e: event) = f(e) }     listeners += kind -> l   }   implicit def unit2eventunit(f: => unit) = (e: event) => f    // works expected   println("1")   listen(1) { e: event => println("a"); println("b") }   println("2")   emit(new event(1))   println("3")    // why not work? "c" should appear between "4" , "d", not "3" , "4"   listen(2) { println("c"); println("d") }   println("4")   emit(new event(2))   println("5") } 

i know work:

implicit def unit2eventunit2(f: () => unit) = (e: event) => f() listen(2) { () => println("c"); println("d") } 

but simpler write:

listen(2) { println("c"); println("d") } 

the compiler sees block in listen(2) { () => println("c"); println("d") }. block not match signature of listen function, returns unit , there implicit conversion unit event => unit, takes last expression in block , applies conversion. that's why result. don't see obvious solution this, ignore parameter in function , write as

listen(2) { _ => println("c"); println("d") } 

then don't need implicit conversion. kind of conversions shouldn't used anyway, because make code hard reason people don't know of conversion , possible source unexpected behavior.


Comments