带有列表的Scala

时间:2018-06-28 11:11:57

标签: scala types either higher-kinded-types

我想实现与Result类型类似的称为Either的类型。主要区别在于,Result类型的左侧应始终为某些内容的列表。什么是正确的类型定义呢?我尝试过这样的事情:

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]

但这在map函数Failure[Any] does not equal Result[List, B]Success[B] does not equal Result[List, B]中出现错误。类型定义Result[List, +A]是否已经错误,我应该使用像List[_]这样的类型更高级的类型吗?

1 个答案:

答案 0 :(得分:2)

如果您希望左侧总是 List,则无需在List上进行抽象。在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]

请注意,似乎您是从Scalaz / Cats重新发明了一些标准Applicative