2016-12-19 5 views
0

この質問はthis other questionに関連しています。そこでは、基本的に単純なケースクラスにインターフェイス実装を取り付けることができます。コアはこのビットです:次の暗黙的な設計を拡張してOptionのケースをカバーする方法はありますか?

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

このオプションの共変割り当てをカバーするために上記の設計を拡張することはできますか?

+1

UserServiceのは、ここで定義されていません。それは何ですか?また、 'val subject:Subject = UserRow(..)'これは動作しません... UserRowは 'Subject'のサブタイプではありません。 :/ – marios

+1

'UserRow(...):Subject' ~~>' toPluggable(UserRow(...)):Subject'。できます。 – HTNW

答えて

1

Option内の既存のimplicitをラップimplicit defを持っている:

implicit def toPluggableOpt[T](t: Option[T])(implicit ev: T => PluggableUserService): Option[PluggableUserService] = t.map(ev) 

これは、暗黙的にPluggableUserServiceに変換することができ、すべてのもののために動作します。任意のファンクタ(Listなど)に簡単に一般化することもできます。あなたが選んだのライブラリから型クラスを考える(scalaz /猫/何でも):

implicit def mapPluggable[T, F[_]: Functor](t: F[T]) 
    (implicit ev: T => PluggableUserService): F[PluggableUserService] = implicitly[Functor[F[_]]].map(t)(ev) 
2

どの程度

implicit def toPluggableOpt(o: Option[UserRow])(implicit us: UserService) = o.map(new toPluggable(_)) 
関連する問題