此问题与this other question有关。在那里,我基本上可以将接口实现附加到一个简单的case类。核心是这一点:
case class UserRow(id: Long, username: String, firstName: String,
lastName : String, ...)
trait PluggableUserService extends be.objectify.deadbolt.scala.models.Subject {
override def roles: List[Role]
}
object PluggableUserService {
implicit class toPluggable(user: UserRow)(implicit userService: UserService)
extends PluggableUserService {
//------------------------------------------------------------------------
override def roles: List[Role] = {
userService.roles(user)
}
}
然后我可以做:
val user : UserRow = UserRow(...)
user.roles
// or even nicer
val subject : Subject = UserRow(..)
subject.roles
但现在我需要能够做到这一点但不起作用:
val subject : Option[Subject] = Some(UserRow(...))
如何扩展上述设计以涵盖此选项协变分配?
答案 0 :(得分:2)
怎么样
implicit def toPluggableOpt(o: Option[UserRow])(implicit us: UserService) = o.map(new toPluggable(_))
答案 1 :(得分:1)
拥有implicit def
封装implicit
中的现有Option
:
implicit def toPluggableOpt[T](t: Option[T])(implicit ev: T => PluggableUserService): Option[PluggableUserService] = t.map(ev)
这适用于可以隐式转换为PluggableUserService
的所有内容。它也可以很容易地推广到任何仿函数(List
等)。给出你选择的库中的Functor[F[_]]
类型类(scalaz / cats / whatever):
implicit def mapPluggable[T, F[_]: Functor](t: F[T])
(implicit ev: T => PluggableUserService): F[PluggableUserService] = implicitly[Functor[F[_]]].map(t)(ev)