2017-08-30 7 views
0

私はScalaとdoobieでプロジェクトに取り組んでいます。私は、MacWireによって注入され、異なるタスク/将来のモナド(例えば、テストのため)で使用されるトランスアクターの形質を実装しようとしています。Scala(doobie):型は不変です

import doobie.imports 
import doobie.imports._ 
import fs2.Task 
import fs2.util.{Catchable, Suspendable} 

trait Transactor[M[_]] { 
    implicit def catchable: Catchable[M] = implicitly 
    val transactor: M[imports.Transactor[M]] 
    def transact[A](q: ConnectionIO[A]): M[A] = catchable.flatMap(transactor)(xa => q.transact(xa)) 
} 

case class H2Transactor[M[_]: Catchable: Suspendable](pure: PureConfig) extends Transactor[M] { 
    override val transactor = doobie.h2.imports.H2Transactor[M](
    pure.config.persistence.name, 
    pure.config.persistence.user.orNull, 
    pure.config.persistence.password.orNull 
) 
} 

... 
trait DatabaseModule { lazy val transactor = wire[H2Transactor[Task]] } 
trait TestModule { lazy val transactor = wire[H2Transactor[IOLite]] } 

しかし、私はこのエラーを取得する:

[error] .../src/main/scala/.../persistence/transactor/H2Transactor.scala:13: type mismatch; 
[error] found : M[doobie.h2.h2transactor.H2Transactor[M]] 
[error] required: M[doobie.imports.Transactor[M]] 
[error]  (which expands to) M[doobie.util.transactor.Transactor[M]] 
[error] Note: doobie.h2.h2transactor.H2Transactor[M] <: doobie.imports.Transactor[M], but type M is invariant in type _. 
[error] You may wish to define _ as +_ instead. (SLS 4.5) 

それはそれはTask[+A]のように定義されているためTaskのために動作しますが、ドゥービー・のIOLiteIOLite[A]として。私はこの仕事をすることができますどのような方法ですか?またはTaskの代わりにdiffer Monadタイプを使用するとがありますか(doobieテストにはIOLiteは変更できません)?

答えて

2

それを試してみてください:

override val transactor = doobie.h2.imports.H2Transactor[M](...).widen 

widenは(catsscalaz両方で)利用可能である操作MFunctorインスタンスを有する場合です。もしAB

+0

のサブクラスならばM[A]M[B]として扱うことができます。これは、次のように助けました: 'オーバーライドトランスアクター:M [imports.Transactor [M]] = Functor [M] .widen [doobie.h2.imports.H2Transactor [M]、imports.Transactor [M]](doobie.h2.imports。 H2Transactor [M](...)) ' –

関連する問題