简体   繁体   中英

How to transform Option[A] to Either[String, B] in Scala with Cats?

I create small code samples where want to show how cats library work. While I was working on the last one example, I noticed that it probably could be more elegant:

import cats.effect.IO
import scala.collection.mutable.HashMap

val storage = HashMap[Int, String]().empty

override def deleteWord(id: Int): IO[Either[String, Unit]] =
  for {
    removedWord <- IO(storage.remove(id))
    result <- IO {
                removedWord.flatMap(_ => Some(())).toRight(s"Word with $id not found")
              }
  } yield result

What is a way to rewrite the code snippet in a more concise form using cats syntax?

You don't need to create another IO, as the expression in yield result will be already wrapped by IO by the for comprehension.

def deleteWord(id: Int): IO[Either[String, Unit]] =
  for {
    removedWord <- IO(storage.remove(id))
    result = removedWord.map(_=>()).toRight(s"Word with $id not found")
  } yield result

Or even

def deleteWord(id: Int): IO[Either[String, Unit]] =
  for (removedWord <- IO(storage.remove(id)))
    yield removedWord.map(_=>()).toRight(s"Word with $id not found")

Maybe you oversimplified your sample, but Cats will not improve such transformation

import scala.collection.mutable.HashMap
import cats.implicits._

val storage = HashMap(1 -> "abc")

def deleteWord(id: Int) =
  storage
    .remove(id)
    .fold(s"Word with $id not found".asLeft[Unit])(_ => ().asRight)

deleteWord(1)
// Either[String, Unit] = Right(())
deleteWord(2)
// Either[String, Unit] = Left("Word with 2 not found")

One of the solutions which I received in gitter cats chat:

import cats.implicits._

override def deleteWord(id: Int): IO[Either[String, Unit]] =
  for {
    removedWord <- IO(storage.remove(id))
    result <- IO(removedWord.toRight(s"Word with $id not found").void)
  } yield result

it seems exactly what I needed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM