0

Compiler complains at Left(e): Expression of type Left(List[ServiceError, Nothing]) doesn't conform to expected type Either[E , R]

sealed trait ServiceResult[+E <: List[ServiceError], +R ] {
      def toEither: Either[E , R] = this match {
        case Success(a) => Right(a)
        case Failure(e) => **Left(e)**
      }
    }

    final case class Success[+R](a: R) extends ServiceResult[Nothing, R] {}

    final case class Failure[+T <: ServiceError](e: List[T]) extends ServiceResult[List[T], Nothing]{}

My requirement is explained below,

So... I have a trait ServiceError. Each Service on backend has their own errors which extends this trait. When I'm doing request for example from rest layer,

val r = subnetService ? GetByIdWithInfo( SubnetId( id ) )
val r2 = r.mapTo[ ServiceResult [ SubnetServiceError, SubnetWithInfoDTO ] ] )

I want to have a type like Either[A,B] but with some additional constraints. In case of error ( or errors ) on server - return List[ServiceError] or return some result.

sarveshseri
  • 13,738
  • 28
  • 47
Deil
  • 492
  • 4
  • 14
  • Where does compiler complains... ? please add full error log. – sarveshseri Feb 20 '15 at 11:22
  • Idea underscore Left(e) with note which I wrote above. Compiler says Error:(17, 10) constructor cannot be instantiated to expected type; found : core.Failure[T] required: core.ServiceResult[E,R] case Failure(e) => Left(e) ^ – Deil Feb 20 '15 at 11:27
  • Well... try `sbt compile` and add the error log in question. – sarveshseri Feb 20 '15 at 11:41
  • [error] /Users/deil/Projects/nms/src/main/scala/core/Result.scala:17: constructor cannot be instantiated to expected type; [error] found : core.Failure[T] [error] required: core.ServiceResult[E,R] [error] case Failure(e) => Left(e) [error] ^ – Deil Feb 20 '15 at 11:49
  • You are trying to do some very strange stuff. This code seems to have lots of problems. Can you please explain the requirement... so that we can suggest some alternative solution. – sarveshseri Feb 20 '15 at 11:50
  • Ok. I have trait ServiceError. Each Service on backend has their own errors which extends that trait. When I'm doing request for example from rest layer (subnetService ? GetByIdWithInfo(SubnetId(id))).mapTo[ServiceResult[SubnetServiceError, SubnetWithInfoDTO]]) I want to have type like Either[A,B] but with some additional constraints. In case of error or errors on server - return List[ServiceError], other way - return some result. – Deil Feb 20 '15 at 12:02
  • I think what you probably want is just `type ServiceResult[ R ] = Either[ List[ ServiceError ], R ]`. – sarveshseri Feb 20 '15 at 12:19

2 Answers2

0

I think what you want is just,

trait ServiceError

trait ServiceResult

type ServiceEither = Either[ List[ ServiceError ], ServiceResult ]

If this does not match your requirement, then tell in the comments.

sarveshseri
  • 13,738
  • 28
  • 47
  • Yes, I know that I can do just like this....but according to my question "How can I make analog of Either?" it's not an answer ) I'm just going crasy about how to make this work... trying to understand scala, variance, type system better. And I don't wont to give up. It seams to me that it's possible to make it works in my way – Deil Feb 20 '15 at 12:34
  • Well... it is possible to do lots of things... but as it is now, your model does not make sense. My suggestion is -don't rush and give it time... make incremental progress. What you need is real understanding and that may take sometime to get. What you are trying to do in this code is kind of similar to using rabbits to create a squirrel that has horns and can speak German, English and French. – sarveshseri Feb 20 '15 at 12:52
  • Ok))))) Maybe you are right) Thank you very much any way. – Deil Feb 20 '15 at 13:07
0

Does the following work for you?

sealed trait ServiceResult[+E <: ServiceError, +R] {
  def toEither: Either[List[E], R] = this match {
    case Success(a) => Right(a)
    case Failure(e) => Left(e)
  }
}

final case class Success[+R](a: R) extends ServiceResult[Nothing, R] {}

final case class Failure[+T <: ServiceError](e: List[T]) extends ServiceResult[T, Nothing] {}