ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Either using cats and ox
    scala/scala3 2024. 4. 4. 19:06

    catsox 를 활용해 Either 를 강력하게 사용하기

     

    Cats Either Helper

    • .asRight .asLeft
    • .leftMap .map
    • Either.catchNonFatal,  Either.catchOnly
    • Either.fromTry, Either.fromOption

    Ox Either Helper

     

    코드

     libraryDependencies += "org.typelevel" %% "cats-core" % "2.10.0",
     libraryDependencies += "com.softwaremill.ox" %% "core" % "0.1.0"
    import cats.*
    import cats.syntax.all.*
    
    import scala.util.{Failure, Try}
    
    enum AppError(val code: Int, val message: String, val detail: String) extends Throwable {
      case BadRequest(override val detail: String) extends AppError(400, "bad request", detail)
      case ServerError extends AppError(500, "server error", "")
    }
    
    @main def Main(): Unit = {
      val e2: Either[Throwable, Int] = Either.catchNonFatal(2)
      val e3: Either[ArithmeticException, Int] = Either.catchOnly[ArithmeticException](1 / 0)
      val e4: Either[AppError, Int] = Either
        .fromTry[Int](Failure(Exception("something wrong")))
        .leftMap(e => AppError.BadRequest(e.getMessage))
      //  val t4: Try[Int] = e4.toTry
    
      import ox.either
      import ox.either.{ok, fail}
    
      val result: Either[Unit | Throwable, Int] = either { // o5 때문에 Left 로 Unit 이 추가됨
        val e1: Either[AppError, Int] = 4.asRight[AppError]
        val v1: Int = e1.ok()
    
        val o5: Option[Int] = none[Int]
        val v2345: Int = v1 match {
          case 2 => e2.ok()
          case 3 => e3.ok()
          case 4 => e4.ok()
          case 5 => o5.ok()  // Option 을 Either 로 변환하지 않더라도 자연스럽게 composing 될 수 있다 !!!
          case _ => AppError.ServerError.fail() // 한번에 탈출(?) 해 최종 결과 either Left 로 직행할 수 있다.
        }
    
        v1 + v2345
      }
    
      result match {
        case Right(v)           => println(s"success: $v") // when v1 == 2
        case Left(e: AppError)  => println(s"error: code=${e.code}, message=${e.message}, detail=${e.detail}") // when v1 == 4
        case Left(e: Throwable) => println(s"error: unknown, ${e.getMessage}") // when v1 == 3
        case Left(())           => println(s"error: option empty") // when v1 == 5
      }
    
      println(result)
    }

     

     

    scala.util.control.Exception.catching

    https://www.scala-lang.org/api/current/scala/util/control/Exception$.html

      import scala.util.control.Exception._
      import java.net._
    
      val s = "https://www.scala-lang.org/"
      val x2: Either[Throwable,URL] = 
        catching(classOf[MalformedURLException], classOf[NullPointerException]).either(new URL(s))

     

    'scala > scala3' 카테고리의 다른 글

    type lambdas  (0) 2024.04.23
    Function Context  (0) 2024.04.12
    play-json 에서 scala3 enum 사용하기  (0) 2024.03.29
    Exports  (0) 2024.03.22
    opaque type  (0) 2024.03.22

    댓글

Designed by Tistory.