如何在带有Cat的Scala中将Option [A]转换为[String,B]中的任何一个?

时间:2019-08-26 15:08:42

标签: scala scala-cats

我创建了一些小的代码示例,以展示cats库的工作方式。当我处理最后一个示例时,我注意到它可能更优雅:

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

使用cats语法以更简洁的形式重写代码段的方法是什么?

3 个答案:

答案 0 :(得分:1)

您无需创建其他IO,因为yield表达式中的表达式已经被IO包裹了以进行理解。

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

甚至

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

答案 1 :(得分:0)

也许您简化了样本,但是Cats不能改善这种转换

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")

答案 2 :(得分:0)

我在猫猫聊天中收到的一种解决方案:

cursor.moveToFirst()
val list = generateSequence {
    cursor.moveToNext()
    getStringFromCursor(cursor)
}.take(cursor.count).toList()

这似乎正是我所需要的