绕过Scala类型推断限制
在我维护的图书馆中,我们有以下特点:绕过Scala类型推断限制,scala,type-inference,Scala,Type Inference,在我维护的图书馆中,我们有以下特点: 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(_ =&g
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)
}
我们通过相关类型的隐式转换提供此特性的实例
这允许我们编写如下表达式:
mayFail ?| BadRequest(_.toString)
或
这种重载使我们能够为lib的用户提供一种简洁的语法,但不幸的是,它不能很好地与lambdas的某些类型推断混合
例如,以下内容不可编译:
mayFail ?| { case SomeError => BadRequest // etc... }
不知何故,scalac无法确定{case XYZ=>…}
是B=>结果
还是=>结果
。(表示扩展函数缺少参数类型)
如果在StepOps
中消除两个方法名称的歧义,一切都会正常工作,但这样做会让人感到有点难过,可能会破坏一些用户的代码
有没有合适的解决方案可以在不改变DSL语法的情况下在库级别解决这个问题
编辑:在@ghik的评论之后添加了更具体的代码片段第二个
?
方法是否总是调用第一个方便的方法?更准确地说,两个具体的?
方法都调用了我没有显示的第三个抽象方法。您可以通过在调用站点键入函数来“修复”这个问题:mayFail({ Heal-Error=> BadRequest //等…}:Error Type=>结果) @ Kolmar,您是对的(我也意识到了这一点),但我不认为它是一个合适的解决方案。我在库级寻求一个解决方案,这样用户就不会被迫添加这种“不雅”类型的归属。
mayFail ?| { case SomeError => BadRequest // etc... }