如何使用 Scala 和 Cats 从 List[OF[String]] 到 F[List[String]]?
How to go from a List[F[String]] to F[List[String]] using Scala and Cats?
我是 Cats 的新手,我不知道如何克服这种情况。在下面的代码中:
class Example[F[_]] {
import cats._
import cats.data._
import cats.syntax.all._
def saveAll(list: List[String])(implicit M: Monad[F]): F[List[String]] = {
val result: List[F[String]] =
list.map(saveOne)
}
def saveOne(s: String)(implicit M: Monad[F]): F[String] = s"Saved $s".pure[F]
}
如何在 saveAll
函数中转换 result
变量,以确保它符合预期的 return 类型?
谢谢。
这种变换是用traverse
操作完成的:
class Example[F[_]] {
import cats._
import cats.implicits._
def saveAll(list: List[String])(implicit M: Monad[F]): F[List[String]] =
list.traverse(saveOne)
def saveOne(s: String)(implicit M: Monad[F]): F[String] =
s"Saved $s".pure[F]
}
正如您在 Traverse
类型 class 中的 traverse
方法签名中所见,它需要 Applicative
的实例,而不是 Monad
:
trait Traverse[F[_]] {
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]
}
在猫中,每个具有 Monad
的类型也有一个 Applicative
,因此 Example
class 甚至可以与 Monad
一起使用。
但反之则不然。有些类型只有一个 Applicative
实例。其中最值得注意的是 Validated
。您可以在 the cats documentation.
中阅读有关为 Validated
实施 Monad
的问题的更多信息
因此,如果您改为请求 Applicative
的实例,此代码将更加通用:
class Example[F[_]] {
import cats._
import cats.implicits._
def saveAll(list: List[String])(implicit M: Applicative[F]): F[List[String]] =
list.traverse(saveOne)
def saveOne(s: String)(implicit M: Applicative[F]): F[String] =
s"Saved $s".pure[F]
}
我是 Cats 的新手,我不知道如何克服这种情况。在下面的代码中:
class Example[F[_]] {
import cats._
import cats.data._
import cats.syntax.all._
def saveAll(list: List[String])(implicit M: Monad[F]): F[List[String]] = {
val result: List[F[String]] =
list.map(saveOne)
}
def saveOne(s: String)(implicit M: Monad[F]): F[String] = s"Saved $s".pure[F]
}
如何在 saveAll
函数中转换 result
变量,以确保它符合预期的 return 类型?
谢谢。
这种变换是用traverse
操作完成的:
class Example[F[_]] {
import cats._
import cats.implicits._
def saveAll(list: List[String])(implicit M: Monad[F]): F[List[String]] =
list.traverse(saveOne)
def saveOne(s: String)(implicit M: Monad[F]): F[String] =
s"Saved $s".pure[F]
}
正如您在 Traverse
类型 class 中的 traverse
方法签名中所见,它需要 Applicative
的实例,而不是 Monad
:
trait Traverse[F[_]] {
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]
}
在猫中,每个具有 Monad
的类型也有一个 Applicative
,因此 Example
class 甚至可以与 Monad
一起使用。
但反之则不然。有些类型只有一个 Applicative
实例。其中最值得注意的是 Validated
。您可以在 the cats documentation.
Validated
实施 Monad
的问题的更多信息
因此,如果您改为请求 Applicative
的实例,此代码将更加通用:
class Example[F[_]] {
import cats._
import cats.implicits._
def saveAll(list: List[String])(implicit M: Applicative[F]): F[List[String]] =
list.traverse(saveOne)
def saveOne(s: String)(implicit M: Applicative[F]): F[String] =
s"Saved $s".pure[F]
}