Использование бесплатной монады с любым

У меня есть два DSL - EmployeeAction а также ContactAction, Вот мои черты (Действия)

Complete Gist: ссылка

sealed trait EmployeeAction[R]
case class GetEmployee(id: Long) extends EmployeeAction[Either[Error, Employee]]

sealed trait ContactAction[R]
case class GetAddress(empId: Long) extends ContactAction[Either[Error, Address]]

Я использовал cats' Coproduct а также Inject Вот моя программа, чтобы получить адрес менеджера:

type Program = Coproduct[EmployeeAction, ContactAction, A]

def findManagerAddress(employeeId: Long)
               (implicit EA: EmployeeActions[Program],
                CA: ContactActions[Program]): Free[Program, Address] = {
  import EA._, CA._
  for {
    employee <- getEmployee(employeeId)
    managerAddress <- getAddress(employee.managerId)
  } yield managerAddress
}

Выше не компилируется, потому что getEmployee возвращает Either[Error, Employee], Как мне справиться с этим в Free для понимания?

Я пытался обернуть EitherT Монадный преобразователь, как показано ниже, не показывает никаких ошибок в IntelliJ, но он не работает при сборке.

for {
  employee <- EitherT(getEmployee(employeeId))
  managerAddress <- EitherT(getAddress(employee.managerId))
} yield managerAddress

Ниже приведена ошибка:

[scalac-2.11] /local/home/arjun/code/Free/src/FreeScalaScripts/src/free/program/Program.scala:71: error: no type parameters for method apply: (value: F[Either[A,B]])cats.data.EitherT[F,A,B] in object EitherT exist so that it can be applied to arguments (cats.free.Free[free.Program,Either[free.Error,free.Employee]])
[scalac-2.11]  --- because ---
[scalac-2.11] argument expression's type is not compatible with formal parameter type;
[scalac-2.11]  found   : cats.free.Free[free.Program,Either[free.Error,free.Employee]]
[scalac-2.11]  required: ?F[Either[?A,?B]]
[scalac-2.11]       employee <- EitherT(getEmployee(employeeId))
[scalac-2.11]                   ^

Как мне разобраться с Either in для понимания и как передать ошибки вызывающей стороне? Я хочу знать, для которого все сотрудники идентифицировали вызов, который потерпел неудачу.

1 ответ

EitherT занимает F[Either[A, B]] но у вас есть Free[Program, Either[Error, Employee]], который не совместим.

Решение для создания псевдонима типа для Free[Program, A]:

type MyAlias[A] = Free[Program, A]

Тогда сделай getEmployee вернуть MyAlias[Either[Error, Employee]] и то же самое для getAddress,

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