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.