【问题标题】:How can I extend the following implicit-based design to also cover the Option case?如何扩展以下基于隐式的设计以涵盖 Option 案例?
【发布时间】:2016-12-19 17:44:11
【问题描述】:

此问题与this other question 有关。在那里,我基本上可以将接口实现附加到一个简单的案例类。核心是这个位:

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(...))

如何扩展上面的设计以涵盖此选项协变赋值?

【问题讨论】:

  • UserService 没有在这里定义。那是什么?此外,val subject : Subject = UserRow(..) 这不应该工作...... UserRow 不是Subject 的子类型。 ://
  • UserRow(...): Subject ~~> toPluggable(UserRow(...)): Subject。它有效。

标签: scala


【解决方案1】:

怎么样

  implicit def toPluggableOpt(o: Option[UserRow])(implicit us: UserService) = o.map(new toPluggable(_))

【讨论】:

    【解决方案2】:

    有一个 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)
    

    【讨论】:

      猜你喜欢
      • 2017-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多