遍历的cats.data.EitherT

时间:2018-08-14 07:34:06

标签: scala scala-cats

我有一个关于将Traverse与EitherT一起使用的问题。假设我们有这样的代码:

def validate(s: String): EitherT[Future, NumberFormatException, Int] = {
  EitherT(Future.successful(try { Right(s.toInt) } catch { case e: 
  NumberFormatException => Left(e)}))
}

List("1", "2").traverse(validate)

很遗憾,此代码无法编译,因为我们缺少以下内容:

error: could not find implicit value for evidence parameter of type cats.Applicative[G] List("1", "2").traverse(validate)

我尝试查找并找到以下答案:Switching between EitherT and Validation to accumulate error or traverseValidation versus disjunction

所以似乎可以找到一些解决方案。但是问题在于,他们两个都在使用traverseU,在scala 2.12中已不再是该选项。那请问怎么办?

编辑 这是包含导入的代码:

import cats.data.EitherT
import cats.syntax.traverse._
import cats.instances.list._
import cats.instances.future._
import scala.concurrent.ExecutionContext.global

import scala.concurrent.Future

def validate(s: String): EitherT[Future, NumberFormatException, Int] = {
  EitherT(Future.successful(try { Right(s.toInt) } catch { case e:
    NumberFormatException => Left(e)}))
}

List("1", "2").traverse(validate)

2 个答案:

答案 0 :(得分:2)

通常,猫会在不同的进口下打包隐含的特定证据。在这种情况下,您需要ListFuture的证明。

  import cats.data.EitherT
  import cats.syntax.traverse._
  import cats.instances.list._
  import cats.instances.future._

  import scala.concurrent.Future

  def validate(s: String): EitherT[Future, NumberFormatException, Int] = {
    EitherT(Future.successful(try { Right(s.toInt) } catch { case e: NumberFormatException => Left(e) }))
  }

  List("1", "2").traverse(validate)

此代码对我来说是用cats 1.2.0编译的。

答案 1 :(得分:0)

import cats.{Applicative, Monad}
import cats.data.EitherT
import cats.syntax.traverse._
import cats.instances.list._
import cats.instances.future._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

def validate(s: String): EitherT[Future, NumberFormatException, Int] = {
    EitherT(Future.successful(try { Right(s.toInt) } catch { case e: NumberFormatException => Left(e) }))
  }

type Tmp[T] = EitherT[Future, NumberFormatException,T]
List("1", "2").traverse[Tmp, Int](validate)

这就是我的工作方式。我必须创建新的类型。