将 IO 列表转换为列表的 IO
Transform a List of IO's into an IO of a List
我想像这样使用 cats-effect 的 IO monad 读取文件列表:
def readFile(file: File): IO[Either[CouldNotReadFromFileError, String]] = ???
// lists all the files I want to read
// returns an Either b/c this might encounter i/o problems
def findFiles(): IO[Either[Throwable, Array[File]]] = ???
// reads all files and saves their content in an Array[String]
// ignores files it could not read or find
def readFiles(): IO[Array[String]] = for {
filesE <- listFiles
files = filesE match {
case Left(err) =>
log.error("An error happened while reading files: " + err.getMessage)
List[File]()
case Right(fs) => fs.toList.map(readFile)
}
// files has type: List[IO[Either[CouldNotReadFromFileError, String]]]
// to continue here I'd like to have a: IO[List[Either[CouldNotReadFromFileError, String]]]
???
} yield ???
现在,为了在 for-yield-construction 中继续我的计算,我想将我的 List[IO[Either[CouldNotReadFromFileError, String]]]
转换为 IO[List[Either[CouldNotReadFromFileError, String]]]
。我知道我可能可以使用 cat's traverse 做这样的事情,但不知道具体怎么做。非常感谢任何帮助。
sequence
满足你的需求:
import java.io.File
import cats.effect.IO
import cats.implicits._
final class CouldNotReadFromFileError extends RuntimeException("message")
object TestTest {
def readFile(file: File): IO[Either[CouldNotReadFromFileError, String]] = ???
def findFiles: IO[Either[Throwable, Array[File]]] =
???
// reads all files and saves their content in an Array[String]
// ignores files it could not read or find
def readFiles(): IO[Array[String]] =
for {
filesE <- findFiles
files = filesE match {
case Left(err) =>
List.empty
case Right(fs) =>
fs.toList.map(readFile)
}
// The type ascription below is just for demonstration purposes.
// You don't need to keep it there.
a <- files.sequence: IO[List[Either[CouldNotReadFromFileError, String]]]
} yield {
???
}
}
我想像这样使用 cats-effect 的 IO monad 读取文件列表:
def readFile(file: File): IO[Either[CouldNotReadFromFileError, String]] = ???
// lists all the files I want to read
// returns an Either b/c this might encounter i/o problems
def findFiles(): IO[Either[Throwable, Array[File]]] = ???
// reads all files and saves their content in an Array[String]
// ignores files it could not read or find
def readFiles(): IO[Array[String]] = for {
filesE <- listFiles
files = filesE match {
case Left(err) =>
log.error("An error happened while reading files: " + err.getMessage)
List[File]()
case Right(fs) => fs.toList.map(readFile)
}
// files has type: List[IO[Either[CouldNotReadFromFileError, String]]]
// to continue here I'd like to have a: IO[List[Either[CouldNotReadFromFileError, String]]]
???
} yield ???
现在,为了在 for-yield-construction 中继续我的计算,我想将我的 List[IO[Either[CouldNotReadFromFileError, String]]]
转换为 IO[List[Either[CouldNotReadFromFileError, String]]]
。我知道我可能可以使用 cat's traverse 做这样的事情,但不知道具体怎么做。非常感谢任何帮助。
sequence
满足你的需求:
import java.io.File
import cats.effect.IO
import cats.implicits._
final class CouldNotReadFromFileError extends RuntimeException("message")
object TestTest {
def readFile(file: File): IO[Either[CouldNotReadFromFileError, String]] = ???
def findFiles: IO[Either[Throwable, Array[File]]] =
???
// reads all files and saves their content in an Array[String]
// ignores files it could not read or find
def readFiles(): IO[Array[String]] =
for {
filesE <- findFiles
files = filesE match {
case Left(err) =>
List.empty
case Right(fs) =>
fs.toList.map(readFile)
}
// The type ascription below is just for demonstration purposes.
// You don't need to keep it there.
a <- files.sequence: IO[List[Either[CouldNotReadFromFileError, String]]]
} yield {
???
}
}