Generic DAO with nested monad interface methods

30 views
Skip to first unread message

ace_coder

unread,
Oct 18, 2016, 12:27:12 PM10/18/16
to scala-user
Hello Scala Users,

I am trying to implement a generic DAO, which can be extended for MongoDB, SQL, etc. I define the interface
methods with a generic type definition, Method[+T]. This type definition is declared by each concrete DAO for
example MongoDB may define it as follows:

    type Method[+T] = Option[T]

For my case I have a concrete implementation that requires:

    type Method[+T] = EitherT[C, A, T]    where C is another monad and A is some other non-important type.

I use scalaz Either transform (EitherT) because I need to be able to compose methods and therefore unwrap
nested monads with for-comprehensions. Without the usage of EitherT I cannot handle situations like
Option[Either[Int, Int]] which correspond to EitherT[Option, Int, Int]. The following code conveys the shortcomings:

Without EitherT:
    case class Reader[+A](f: A => Either[Int, Int]) {
        def apply(v: A): Either[Int, Int] = f(v)
    }

    def foo() = Reader( a:Int => Right( a+1 ) )

    val bar: Either[Int, Int] = for {
        b <- foo().apply(9).right
    } yield b

With EitherT:
    def foo() = EitherT( Reader( a:Int => Right( a+1 ) ) ) 

    val bar: EitherT[Reader, Int, Int] = for {
        b <- foo()
    } yield b

    b.run(9)

As you can see the second implementation is much cleaner, however it causes compile time issues.

The problem with this approach is that +T is covariant and is supplied to a covariant position in EitherT[ F[ _ ], A, B ].

Any assistance is greatly appreciated. Thank you!
Reply all
Reply to author
Forward
0 new messages