1
votes

Suppose I have a scope A in which some implicit values are defined, and a code block c that uses those implicit values. I also have scope B which has implicits of compatible type, so that if I copy the code block c into B, it would compile and run without problem. This is ugly, of course, since I'm duplicating c in two places, so I would like to move c into its own function. Now, the function signature of c has to look like:

def c(args...)(implicit implicitArgs...) = ...

where implicitArgs are the implicit values used in c. Given that some frameworks (Scalding, in my case) defines many implicits, the signature here can quickly get out-of-hand. Is there any syntax to say "carry all implicit values in the calling scope"? Or is there a clever way around this?

cheers, Geoff

2

2 Answers

0
votes

Not sure if this would work, but you can give it a try. You could group implicits into container objects.

Example: Let's say you have implicits of type X, Y and Z, and you don't always want to add three implicit arguments to every method. Say you define a container object for those:

class MyImplicits(val x:X, val y:Y, val z:Z)

In order to allow for automatic creation of the MyImplicits wrapper, you create an object method that derives it from the individual implicits. Likewise, you define implicit un-wrapper methods:

object MyImplicits {
  implicit def wrap(implicit x:X, y:Y, z:Z):MyImplicits = new MyImplicits(x, y, z)
  implicit def unwrapX(implicit wrapper:MyImplicits):X = wrapper.x
  implicit def unwrapY(implicit wrapper:MyImplicits):Y = wrapper.y
  implicit def unwrapZ(implicit wrapper:MyImplicits):Z = wrapper.z
}

Let's say we have a method like this:

def foo(...)(implicit implicits:MyImplicits) = ...

The following should work:

implicit val implicitXIsInScope:X = ...
implicit val implicitXIsInScope:Y = ...
implicit val implicitXIsInScope:Z = ...
foo(...) // MyImplicits should automatically be created

Likewise, if an instance of MyImplicits is in implicit scope, you should be able to call any method that requires an implicit instance of X without needing to unwrap it explicitly.

I did not try this out though. Please let me know if it works!

0
votes

I found a way to "curry implicit args":

def myfunc(arg:Something)(implicit session:Otherthing):Unit = ....

val curriedFunc = myfunc(value)(_:Otherthing)

curriedFunc(valueOfOtherThing)

For more information see Partials without Currying at http://www.codecommit.com/blog/scala/function-currying-in-scala

Note: I'm new to Scala and I don't know all best-practices.