Can I turn a method which takes an implicit parameter into a function?
trait Tx
def foo(bar: Any)(implicit tx: Tx) {}
foo _ // error: could not find implicit value for parameter tx: Tx
I am trying to achieve the following, preferably if I can somehow make it work with the plain call withSelection(deleteObjects)
:
trait Test {
def atomic[A](fun: Tx => A): A
def selection: Iterable[Any]
def withSelection(fun: Iterable[Any] => Tx => Unit) {
val sel = selection
if (sel.nonEmpty) atomic { implicit tx =>
fun(sel)(tx)
}
}
object deleteAction {
def apply() {
withSelection(deleteObjects) // !
}
}
def deleteObjects(xs: Iterable[Any])(implicit tx: Tx): Unit
}
I found this question, however it does not deal with the lifting from methods to functions as far as I can see.
Implicits only work for methods. But you have to pass a function to
withSelection
. You can get around by wrapping the method in a function:Its impossible to pass
deleteObjects
directly becausefoo _
does not work for afoo
with an implicit parameter list defined.To the best of my knowledge, implicit resolution must take place at usage site, and cannot be curried away. My own moment of disappointment was when I was trying to work around ´ExecutionContext´ proliferation in my code.
One compromise I've been considering was:
The ´implicit´ only holds within the function -- we have to compromise on invocation:
Another compromise -- the one I chose and lived to regret:
This changes the usage from the naive (but desired):
To the following:
Depending on your context, this could be bearable. You could add a ´def transactional´ where I used ´def async´.
I do regret this however, as it complicates inheritance, and incurs some allocation overhead (though that should be JITed away).
Bottom line is that you'll have to come up with a more explicit piecemeal method of invoking your function -- one that is less elegant than currying alone.