Я пытаюсь реорганизовать свой код SCALA в проекте (Play Framework 2.4), когда я пришел с этой идеей:Scala применения с частично определённая функция() не то же самое, как .Не()
(Для того, чтобы обеспечить минимальный рабочий пример, я изменил некоторые классы, например, я изменил результат и будущее [Результат] с 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)
}
}
код выше компилируется.
Тогда я, хотя: я должен ограничивать кратную [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()), который он компилирует. Почему это происходит? call() и .apply() в классе должны быть одинаковыми, не так ли?
Компилятор, похоже, запрашивает тип возврата (Int или Option [Int]) для передачи в PartialFunction вместо типа CanBeAuthenticatedRequest.
Отлично, спасибо! – vicaba
@vicaba Кроме того, вместо вызова 'apply', другим распространенным обходным путем является назначение частичного fuction для val сначала перед его вызовом. Например. 'val f = fold (аутентифицированный) (не прошедший проверку подлинности)' 'f (request)' – dcastro