Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对Scala Future[或]的优雅处理_Scala_Either - Fatal编程技术网

对Scala Future[或]的优雅处理

对Scala Future[或]的优雅处理,scala,either,Scala,Either,我有一种形状如下的类型: val myType: Future[Either[MyError, TypeA]] = // some value case class MyException(e: MyError) extends Exception def eitherToException[A](f: Future[Either[MyError,A]]): Future[A] = { f.flatMap { case Left(e) => Future.failed(My

我有一种形状如下的类型:

val myType: Future[Either[MyError, TypeA]] = // some value
case class MyException(e: MyError) extends Exception

def eitherToException[A](f: Future[Either[MyError,A]]): Future[A] = {
  f.flatMap {
    case Left(e) => Future.failed(MyException(e))
    case Right(x) => Future.successful(x)
  }
}

val myType2 = eitherToException(myType)

我知道我可以在此基础上进行模式匹配,并得到右边或左边的类型,但问题是我必须嵌套我的模式匹配逻辑。我在寻找更优雅的处理方式?有什么建议吗?

如果您将
MyError
编码为例外,您也不再需要
了,可以简单地对完成进行模式匹配,或者使用
recoverWith
将其映射到另一种类型:

myType.onComplete {
  case Success(t) =>
  case Failure(e) =>
}
要映射现有的
类型,可以执行以下操作:

val myType: Future[Either[MyError, TypeA]] = // some value
case class MyException(e: MyError) extends Exception

def eitherToException[A](f: Future[Either[MyError,A]]): Future[A] = {
  f.flatMap {
    case Left(e) => Future.failed(MyException(e))
    case Right(x) => Future.successful(x)
  }
}

val myType2 = eitherToException(myType)
或者,如果
MyError
TypeA
在您的控制下,您可以创建一个通用的超级类型和模式匹配:

sealed trait MyResult
final case class MyError() extends MyResult
final case class TypeA() extends MyResult

myType.map {
  case MyError() => ...
  case TypeA() => ...
}

如果将
MyError
编码为例外,则不再需要
,只需根据完成情况进行模式匹配,或使用
recoverWith
将其映射到其他类型:

myType.onComplete {
  case Success(t) =>
  case Failure(e) =>
}
要映射现有的
类型,可以执行以下操作:

val myType: Future[Either[MyError, TypeA]] = // some value
case class MyException(e: MyError) extends Exception

def eitherToException[A](f: Future[Either[MyError,A]]): Future[A] = {
  f.flatMap {
    case Left(e) => Future.failed(MyException(e))
    case Right(x) => Future.successful(x)
  }
}

val myType2 = eitherToException(myType)
或者,如果
MyError
TypeA
在您的控制下,您可以创建一个通用的超级类型和模式匹配:

sealed trait MyResult
final case class MyError() extends MyResult
final case class TypeA() extends MyResult

myType.map {
  case MyError() => ...
  case TypeA() => ...
}

您可以创建自定义提取器对象:

object FullSuccess {
  def unapply[T](x: Try[Either[MyError, T]]) = x match {
    case Success(Right(x)) => Some(x)
    case _ => None
  }
}

object PartSuccess {
  def unapply[T](x: Try[Either[MyError, T]]) = x match {
    case Success(Left(err)) => Some(err)
    case _ => None
  }
}


您可以创建自定义提取器对象:

object FullSuccess {
  def unapply[T](x: Try[Either[MyError, T]]) = x match {
    case Success(Right(x)) => Some(x)
    case _ => None
  }
}

object PartSuccess {
  def unapply[T](x: Try[Either[MyError, T]]) = x match {
    case Success(Left(err)) => Some(err)
    case _ => None
  }
}


不将MyResult作为超级类型是行不通的,我觉得为了它而利用继承不是一个好主意!TypeA只是一个例子,因为我的所有服务方法都返回一个带有MyError或服务方法正在处理的相应case类类型的!我认为最优雅的解决方案是涉及myFuture.onComplete并使MyError成为例外的解决方案。这很有道理,很有效,很优雅。撇开评论不谈,@sparkr检查你的举止,朋友。@Arne:谢谢你的帖子,但我对以蛋糕模式的名义使用无意义的继承结构感到非常恼火,因为继承类和继承类根本没有关系!对不起,如果我不礼貌的话@斯巴克:没问题。密封的特征编码case类是消息传递的常见模式,例如Akka。与OO语言相比,它确实闻起来像是继承错误的使用,但作为一种scala模式(我最近做了很多Akka,所以我的思维在一个消息框架中)是被广泛接受的。不!将MyResult作为超级类型是行不通的,我觉得为了它而利用继承不是一个好主意!TypeA只是一个例子,因为我的所有服务方法都返回一个带有MyError或服务方法正在处理的相应case类类型的!我认为最优雅的解决方案是涉及myFuture.onComplete并使MyError成为例外的解决方案。这很有道理,很有效,很优雅。撇开评论不谈,@sparkr检查你的举止,朋友。@Arne:谢谢你的帖子,但我对以蛋糕模式的名义使用无意义的继承结构感到非常恼火,因为继承类和继承类根本没有关系!对不起,如果我不礼貌的话@斯巴克:没问题。密封的特征编码case类是消息传递的常见模式,例如Akka。与OO语言相比,它闻起来确实像是继承错误使用,但作为一种scala模式(我最近做了很多Akka,所以我的思维在一个消息框架中)它听起来像是需要monad transformers,不幸的是scala核心没有提供。scalaz中可比较的类型是
EitherT[Task,MyError,TypeA]
。你可以用一种合理的方式在上面做一些操作,比如
map
flatMap
,等等。不!使用scalaz不是此项目的选项!不能添加依赖项?我想你可以自己玩
游戏吗?我终于做到了!我自己想出了一个更进一步的实现!听起来你需要monad变压器,不幸的是scala内核没有提供。scalaz中可比较的类型是
EitherT[Task,MyError,TypeA]
。你可以用一种合理的方式在上面做一些操作,比如
map
flatMap
,等等。不!使用scalaz不是此项目的选项!不能添加依赖项?我想你可以自己玩
游戏吗?我终于做到了!我自己想出了一个更进一步的实现!