Преобразуйте список IO в IO списка - PullRequest
0 голосов
/ 13 февраля 2019

Я хочу прочитать список файлов, используя cats-effect монаду ввода-вывода, например:

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 IЯ хотел бы превратить мой List[IO[Either[CouldNotReadFromFileError, String]]] в IO[List[Either[CouldNotReadFromFileError, String]]].Я знаю, что могу, вероятно, сделать что-то подобное, используя кошачий ход , но не могу понять, как именно.Любая помощь с благодарностью.

1 Ответ

0 голосов
/ 13 февраля 2019

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 {
      ???
    }
}
...