将Throwable扔在\ /。fromTryCatch中 - 并正确对齐方法类型

时间:2014-09-22 16:04:29

标签: scala scalaz

我有以下现有方法:

def test: \/[Throwable, Person] = {
  \/.fromTryCatch {
    //existing logic has potential to throw exception (from calls like .toInt) etc
    //now via following for comprehension want to combine Throwable with return type \/[Throwable,Person]
    for {
      p <- q.firstOption.\/>(new Throwable("can't find record for person with id = " + id))
    } yield p
  }
}

产生以下错误:

type mismatch; found : scalaz.\/[Throwable,Person] (which expands to) scalaz.\/[Throwable,Person] required:Person

如何将for-comprehension的返回类型与def test的类型对齐?

1 个答案:

答案 0 :(得分:0)

fromTryCatch需要一个评估为Person的值,这可能会引发异常。

因此,您不需要在\/中包装异常,只需在fromTryCatch块中抛出一个异常,它就会被捕获并自动包装。

或者您可以简单地删除fromTryCatch,因为您已经在\/[Throwable, Person]中实现了例外情况,例如

def test : \/[Throwable,Person] =
  for {
    p <- q.firstOption.\/>(new Throwable(s"can't find record for person with id = $id))
  } yield p

如果您需要将两者混合使用,则可以执行类似

的操作
def test : \/[Throwable,Person] = \/.fromTryCatch {
  mayThrow()

  val res = for {
    p <- q.firstOption.\/>(new Throwable("can't find record for person with id ="+id))
  } yield p

  res match {
    case \/-(p) => p
    case -\/(e) => throw e
  }
}

或更好,您可以将范围分开并仅在必要时使用fromTryCatch,例如

def test : \/[Throwable,Person] =
  for {
    _ <- \/.fromTryCatch { mayThrow() } 
    p <- q.firstOption.\/>(new Throwable("can't find record for person with id ="+id))
  } yield p