Implicit conversions, type parameters, overloading, and anonymous functions syntax

Viewed 79

So, I was trying to "pimp" my Futures (among other things) a little bit with something like this:

implicit class Pimp[T](val x: T) extends AnyVal  {
  def ->>[R](f: T => R): R = f(x)
  def ->>[R](r: => R): R = r
  def <<-(f: T => Unit): T = f.andThen(_ => x).apply(x)
  def <<-(f: => Unit): T = <<- { _ => f }
}

For some reason, when I try to do this now:

Future(1) ->> { Await.result(_, 1 seconds) }

it fails with error: missing parameter type for expanded function ((x$1) => Await.result(x$1, 1.seconds))

But this works:

Future(1) <<- { Await.result(_, 1 seconds) }

So, the question is what is wrong with the first case. What am I doing wrong, and how to make it work. I even tried this (not at all what I want, because it is way too verbose): Future(1) --> { case x: Future[Int] => Awayt.result(_, 1 seconds) }, but even this fails for some reason (still says the parameter type is unknown - how is it unknown, if I explicitly specify it???)

I suspect, the difference between the first case and second is that ->> has a type param, while <<- does not ... But even this Future(1) ->>[Int] { Await.result(_, 1 seconds) } still does not work :(

Update Ok, so, I found one way in which it works:

Future(1) ->> { (f:Future[Int]) => Await.result(f, 1 seconds) }

This kinda defeats the purpose of my implicit though, because of how verbose it is :( Is there any way to make it infer the parameter type without spelling it out like it does in the other case?

Update 2 One more thing. Removing the overloaded "flavor" of ->> from Pimp makes the other case work. I.e., if I only leave

def ->>[R](f: T => R): R = f(x)

in the definition of Pimp, then

Future(1) ->> { Await.result(_, 1 seconds) }

beautifully works as intended.

Having thought about it for a while, I think, that the problem is that in the overloaded case foo ->> { _ => bar } is ambiguous: it could mean "return bar", or "return a function foo => bar". This does not explain however why foo ->>[Bar] { _ => bar } does not work.

1 Answers
Related