In a library I maintain, we have the following trait :
trait StepOps[A, B] {
def failWithHandler(handler: B => Result): Step[A]
def ?|(failureHandler: B => Result): Step[A] = failWithHandler(failureHandler)
def ?|(failureThunk: => Result): Step[A] = failWithHandler(_ => failureThunk)
}
We provide instances of this trait via implicit conversions from the relevant types.
This allows us to write expressions like :
mayFail ?| BadRequest(_.toString)
or
mayFail ?| InternalServerError("woops")
This overloading enables us to provide a nice and concise syntax to the users of the lib, but unfortunately, it doesn't mix very well with some cases of type inference for lambdas.
For exemple, the following doesn't compile :
mayFail ?| { case SomeError => BadRequest // etc... }
Somehow, scalac can't decide wether the { case XYZ => ... }
is a B => Result
or a => Result
. (it says missing parameter type for expanded function
)
If be disambiguate the names of the two methods in StepOps
everything works fine, but doing so would feel a bit sad, and would probably break some of our users code.
Is there a proper solution to work that out at the library level, without changing our DSL's syntax ?
edit : added more specific code snippet following @ghik's comment