-
Either using cats and oxscala/scala3 2024. 4. 4. 19:06
cats 와 ox 를 활용해 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