Scala用()应用PartialFunction与.apply()不同



我试图重构我的scala代码在一个项目(Play Framework 2.4)当我想到这个想法:

(为了提供一个最小的工作示例,我已经更改了一些类,例如,我已经将Result和Future[Result]分别更改为Int和Option[Int])

object ParFuncApply {
  trait CanBeAuthenticatedRequest[A]
  trait AuthenticatedRequest[A] extends CanBeAuthenticatedRequest[A]
  trait UnauthenticatedRequest[A] extends CanBeAuthenticatedRequest[A]

  private def fold[T](authenticated: (AuthenticatedRequest[_]) => T)
                             (unauthenticated: (UnauthenticatedRequest[_]) => T):
  PartialFunction[CanBeAuthenticatedRequest[_], T] = {
    case ar: AuthenticatedRequest[_] => authenticated(ar)
    case ur: UnauthenticatedRequest[_] => unauthenticated(ur)
  }
  def apply(request: CanBeAuthenticatedRequest[_])
           (authenticated: (AuthenticatedRequest[_]) => Int)
           (unauthenticated: (UnauthenticatedRequest[_]) => Int): Int = {
    fold(authenticated)(unauthenticated)(request)
  }
  def async(request: CanBeAuthenticatedRequest[_])
           (authenticated: (AuthenticatedRequest[_]) => Option[Int])
           (unauthenticated: (UnauthenticatedRequest[_]) => Option[Int]): Option[Int] = {
    fold(authenticated)(unauthenticated)(request)
  }
}

以上代码可以编译。

然后我想:我应该将fold[T]参数化类型限制为Int和Option[Int],所以我添加了:

object ParFuncApply {
  trait CanBeAuthenticatedRequest[A]
  trait AuthenticatedRequest[A] extends CanBeAuthenticatedRequest[A]
  trait UnauthenticatedRequest[A] extends CanBeAuthenticatedRequest[A]
  sealed trait Helper[T]
  object Helper {
    implicit object FutureResultHelper extends Helper[Option[Int]]
    implicit object ResultHelper extends Helper[Int]
  }
  private def fold[T: Helper](authenticated: (AuthenticatedRequest[_]) => T)
                             (unauthenticated: (UnauthenticatedRequest[_]) => T):
  PartialFunction[CanBeAuthenticatedRequest[_], T] = {
    case ar: AuthenticatedRequest[_] => authenticated(ar)
    case ur: UnauthenticatedRequest[_] => unauthenticated(ur)
  }
  def apply(request: CanBeAuthenticatedRequest[_])
           (authenticated: (AuthenticatedRequest[_]) => Int)
           (unauthenticated: (UnauthenticatedRequest[_]) => Int): Int = {
    fold(authenticated)(unauthenticated)(request)
  }
  def async(request: CanBeAuthenticatedRequest[_])
           (authenticated: (AuthenticatedRequest[_]) => Option[Int])
           (unauthenticated: (UnauthenticatedRequest[_]) => Option[Int]): Option[Int] = {
    fold(authenticated)(unauthenticated)(request)
  }
}

但这段代码不再编译,相反,如果我改变:fold(authenticated)(unauthenticated)(request)fold(authenticated)(unauthenticated).apply(request)(我已经添加了一个显式调用apply()),它编译。为什么会发生这种情况?在类上调用()和。apply()应该是相同的,不是吗?

编译器似乎要求将返回类型(Int或Option[Int])传递给PartialFunction,而不是CanBeAuthenticatedRequest类型。

因为你在' fold[T: Helper]'中定义了一个上下文绑定,编译器将添加另一个参数列表。换句话说,上下文绑定只是

的语法糖
private def fold[T](authenticated: (AuthenticatedRequest[_]) => T)
                   (unauthenticated: (UnauthenticatedRequest[_]) => T)
                   (implicit helper: Helper[T): PartialFunction[CanBeAuthenticatedRequest[_], T] 

所以当你调用

fold(authenticated)(unauthenticated)(request)

编译器认为request应该是显式指定的隐式Helper[T]。

相关内容

  • 没有找到相关文章

最新更新