0

I wanted to implement a similar type called Result to the Either type. The main difference is, that the Left side of the Result type should always be a List of something. What would be the right type definition for this? I tried having something like that:

sealed trait Result[List, +A] {
    def map[B](f: A => B): Result[List, B] = this match {
        case Failure(err) => Failure(err)
        case Success(value) => Success(f(value))
    }
    def apply[B](f: Result[List, A => B]): Result[List, B] = (f, this) match {
        case (Failure(fE), Failure(aE)) => Failure(fE ::: aE)
        case ...
    }
}

final case class Failure[+E](errors: List[E]) extends Result[List[E], Nothing]
final case class Success[+A](value: A) extends Result[Nothing, A]

But this runs in an error in the map function saying Failure[Any] does not equal Result[List, B] and Success[B] does not equal Result[List, B]. Is the type definition Result[List, +A] already wrong, should I use a higher-kinded type like List[_] instead?

Lando-L
  • 843
  • 6
  • 19

1 Answers1

2

If you want that the left side is always List of something, then there is no need to abstract over the List. Abstract over E:

sealed trait Result[+E, +A] {
    def map[B](f: A => B): Result[E, B] = this match {
        case Failure(err) => Failure(err)
        case Success(value) => Success(f(value))
    }
    def apply[B, F >: E](f: Result[F, A => B]): Result[F, B] = (f, this) match {
        case (Failure(fE), Failure(aE)) => Failure(fE ::: aE)
        case (Failure(fE), _) => Failure(fE)
        case (_, Failure(aE)) => Failure(aE)
        case (Success(fS), Success(tS)) => Success(fS(tS))
    }
}

case class Failure[+E](errors: List[E]) extends Result[E, Nothing]
case class Success[+A](value: A) extends Result[Nothing, A]

Note that it looks as if you are reinventing some standard Applicatives from Scalaz/Cats.

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93
  • I still get the same error Saying Failure[Any] doesn't equal Railway[E,B], and I need the List properties if I want to implement some kind of apply function. I'll update my question to explain that – Lando-L Jun 28 '18 at 11:26
  • @Lando-L the above code definitely compiles. I've updated the `apply` part. My guess is that you've done something wrong with the variance annotations. – Andrey Tyukin Jun 28 '18 at 11:50
  • I don't know what I have done wrong, I thought I had the exact same code. Thank you! – Lando-L Jun 28 '18 at 12:00
  • @Lando-L I assume it was a missing `+` before `List` somewhere. Does it work now? – Andrey Tyukin Jun 28 '18 at 12:01