0

目前,我的目标是使用 CRUD 方法与 DB 进行通信。在简单的操作之间我可能有一些额外的步骤(额外的业务逻辑可能会引发一些错误)。

import cats.effect.IO
import scalikejdbc._

IO(NamedDB(MyDB) localTx {
  implicit session => {
   val x = for {
      a <- IO(select()) // Option[Something]  (1)
      _ <- IO(log(a)) // Option[Something]  (2)
      _ <- IO(insert()) // Something (3)
      _ <- IO(insert()) // Something (4)
      c <- IO(select()) // Option[Something] (5)
      r <- IO(fileSystemOperation(a, c)) // (6)
      _ <- operation(r) // Either[Throwable, Unit] (7)
    } yield ()

    x.unsafeRunSync() // (8)
  }
}).attempt.unsafeRunSync() match { // (9)
  case Left(value) => println("Error")
  case Right(value) => println("Success") // in reality i want to return some result here
}

第一个问题出现(2):我收到错误:

错误类型不匹配;发现:cats.effect.IO[Unit] required: Option[?] _ <- IO(log(a))

但是,如果我记录任何插入((3)(4))的结果,那么一切正常。可能是因为结果类型Option[Something]vs的不同Something,但我认为它会与此相同:

for {
    a <- Option(1)
    ....
}

第二个问题是如何正确处理(7)回滚事务中的错误?我是否必须使用模式匹配并执行以下操作:

operation(r) match {
    case Left(e) => throw e
}

或者我可以在我的内部抛出错误operation并返回Unit而不是Either[Throwable, Unit]

(8)另外,我对and有疑问(9)。是否是开始实际处理和处理任何错误的正确方法?

我尝试使用这种方法执行相同的步骤:

select() match {
    case Some(_) =>
        .....
        operation(r) match {
            case Left(e) => throw e
            case Right(_) => ....
        }
    case None => ....
}

但结果我得到了太深的match-case条款,很难阅读和理解。我是 FP 的新手,但我想以 FP 的方式实现它。

4

0 回答 0