Как совместить Клейсли [M, A, C] и Клейсли [M, B, C]

Я следую за дизайном превосходной книги Reactive Domain Modeling, и мне нужно смешать Kleisli с разными типами:

object CombinedKleisli {
  type User = String
  type Project = String

  trait UserRepo
  trait ProjectRepo
  trait UserService {
    def findByUserId : Kleisli[Future, UserRepo, User]
  }
  trait ProjectService {
    def findProjectById : Kleisli[Future, ProjectRepo, Project]
  }
  trait ComposedService extends UserService with ProjectService {
    for {
      user <- findByUserId
      project <- findProjectById
    } yield (user, project)
  }

}

И так как типы не совпадают, я получаю следующую ошибку компиляции

Error:(28, 15) type mismatch;
 found   : scalaz.Kleisli[scala.concurrent.Future,domain.service.ServiceTest.ProjectRepo,(domain.service.ServiceTest.User, domain.service.ServiceTest.Project)]
    (which expands to)  scalaz.Kleisli[scala.concurrent.Future,domain.service.ServiceTest.ProjectRepo,(String, String)]
 required: scalaz.Kleisli[scala.concurrent.Future,domain.service.ServiceTest.UserRepo,?]
      project <- findProjectById
              ^

Каков наилучший способ исправить это, создав

trait Context {
  def userRepo
  def projectRepo
}

и загрязнять UserService а также ProjectService с этим?

1 ответ

Решение

Вам нужно будет придумать способ объединить типы ввода в один тип. Одним из способов сделать это было бы наследование - у вас был бы тип UserRepo with ProjectRepo это подкласс обоих UserRepo а также ProjectRepo, Другим способом будет состав, где у вас есть кортеж (UserRepo, ProjectRepo),

В обоих случаях вы обычно используете local "расширить" типы ввода каждой стрелки, чтобы вы могли составить их в for-comprehension:

for {
  user <- findByUserId.local[(UserRepo, ProjectRepo)](_._1)
  project <- findProjectById.local[(UserRepo, ProjectRepo)](_._2)
} yield (user, project)

Здесь (UserRepo, ProjectRepo) Параметр типа аргумент определяет новый тип ввода и значение аргумента (например, _._1) определяет, как получить исходный тип ввода стрелки из нового типа ввода.

Другие вопросы по тегам