【问题标题】:How to go from a List[F[String]] to F[List[String]] using Scala and Cats?如何使用 Scala 和 Cats 从 List[F[String]] 到 F[List[String]]?
【发布时间】:2018-10-14 23:36:41
【问题描述】:

我是 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 变量,以确保它与预期的返回类型匹配?

谢谢。

【问题讨论】:

    标签: scala scala-cats


    【解决方案1】:

    这种转换是通过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 类型类中的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 类甚至可以与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]
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-11
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 2019-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多