The best way I've been able to pull this off is by defining a class which holds the curried type information then uses the apply
method to simulate the function call.
I've written about this here - http://caryrobbins.com/dev/scala-type-curry/
For your specific example, you'd need to put the implicit ev: Writes[A]
in the signature for the apply
and not in the signature for foo
. This is because it causes ambiguity between explicitly passing the implicit argument or implicitly calling the apply
method.
Here's an example implementation for your example -
object Example {
def foo[A]: _Foo[A] = _foo.asInstanceOf[_Foo[A]]
final class _Foo[A] private[Example] {
def apply[B, C](b: B, c: C)(implicit ev: Writes[A]): Unit = ???
}
private lazy val _foo = new _Foo[Nothing]
}
You can then supply your type parameter you wish to curry and the following arguments passed to the apply
method will be inferred.
Example.foo[Int]("bar", new Object)
If you do end up needing to specify the other type parameters, you can do so by explicitly calling apply
; although, I've never seen a need to do this yet.
Example.foo[Int].apply[String, Object]("bar", new Object)
If you don't wish to use the intermediate type you can also use a structural type, which I discuss in the aforementioned post; however, this requires reflectiveCalls
and an inferred type signature, both of which I like to avoid.