Scala - как использовать цикл foreach для блока понимания? - PullRequest
0 голосов
/ 11 ноября 2019

У меня есть простой код:

 override def createContributorsList(url: String, params: String): F[List[Contributor]] = getContributorsFromClient(url, params).fold[List[Contributor]](_ => List(), res => res)

 override def createReposList(organization: String, params: String): F[List[GitRepository]] = getReposFromClient(organization, params).fold[List[GitRepository]](_ => List(), res => res)

Этот код возвращает список репозиториев из github и список вкладов. Но теперь мне нужно вызывать createContributorsList для каждого хранилища, которое я нашел по createReposList. Я сделал блок for comprehension:

val stats = new StatisticsRepository[IO](new GitHttpClient[IO])
val res = for {
    repos <- stats.createReposList("github", "")
  } yield repos

Работает нормально, найдены репозитории для данной организации (github). Поэтому я попытался сделать это так:

val res = for {
    repos <- stats.createReposList("github", "")
    list = repos.foreach(repo => stats.createContributorsList(repo.contributors_url, ""))
  } yield (repos, list)

Но list всегда пуст. Я не знаю, как я мог бы сделать это без for comprehension, потому что я оперирую здесь на Monads как IO. Как мне создать код для циклического повторения каждого репо из repos и вызова stats.createContributorsList для каждого?

1 Ответ

2 голосов
/ 11 ноября 2019

Попробуйте flatTraverse

import cats.syntax.flatMap._
import cats.syntax.functor._
import cats.syntax.traverse._
import cats.instances.list._

val res: F[(List[GitRepository], List[Contributor])] = for {
  repos <- stats.createReposList("github", "")
  list <- repos.flatTraverse(repo => stats.createContributorsList(repo.contributors_url, ""))
} yield (repos, list)

foreach возврат Unit, так что это не то, что вам нужно.

...