猫:使用函数映射,结果为 F[_]

Cats: Map with a function which results in F[_]

我有一个功能:

def mapIt(id: Int): F[String]

如果在案例的构造函数中使用结果,使用它映射集合的最佳方法是什么class?我目前正在做这样的事情:

List(1, 2, 3, 4).map( id => mapIt(id).map(SomeCaseClass(id, _))).toList.sequence

你可以将一些 Monad[Int] 映射到 Monad[SomeCaseClass] 只需使用 map 函数(如果 FMonad 那么它可以转换为 List 使用 cats.instances.list 中的 ListInstances.catsStdInstancesForList)。之后,您只需要 flatMap 您的 Int 列表到 SomeCaseClass 列表中:

import cats.Monad
import cats.instances.list._
import scala.language.higherKinds

case class SomeCaseClass(id: Int, name: String)

def mapIt[F[_]: Monad](id: Int): F[String] = Monad[F].pure((id + 10).toString)

List(1, 2, 3, 4).flatMap(id => mapIt(id).map(x => SomeCaseClass(id, x)))
//List(
//  SomeCaseClass(1,11), 
//  SomeCaseClass(2,12), 
//  SomeCaseClass(3,13), 
//  SomeCaseClass(4,14)
//)

更详细的解释

在函数中 mapIt:

def mapIt[F[_]: Monad](id: Int): F[String]

编译器期望一些 F[_] 应该有一些 Monad 隐式。 当您在 flatMap 函数中调用 mapIt 时,编译器会在 Int:

上寻找一些 Monad
List(1, 2, 3, 4).flatMap{
  id => mapIt(id) // looking for Monad[Int]
}

并在导入的实例中找到它: import cats.instances.list._

来自 ListInstances:

implicit val catsStdInstancesForList: Traverse[List] with Alternative[List] with Monad[List] with CoflatMap[List] =
    new Traverse[List] with Alternative[List] with Monad[List] with CoflatMap[List] { ... }

在它仅使用普通 Monad 并将 Int 映射到 SomeCaseClass 之后。最后它只是将 SomeCaseClass 中的 List 压平成。