2

J'ai deux DSLs - EmployeeAction et ContactAction. Voici mes traits (Actions)Utilisation de Monad gratuit avec un ou l'autre

Gist complète: link

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]] 

J'ai utilisé cats 'Coproduct et Inject voici mon programme pour obtenir l'adresse du gestionnaire:

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 
} 

Les ci-dessus doesn « t compilez parce que getEmployee retourne un Either[Error, Employee]. Comment puis-je gérer cela dans Free pour la compréhension?

J'ai essayé d'emballer avec EitherT transformateur monad comme ci-dessous, il montre aucune erreur dans IntelliJ, mais il échoue lors de la construction.

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

Ci-dessous est l'erreur:

[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]     ^

Comment puis-je gérer soit dans la compréhension et à la façon de propager les erreurs à l'appelant? Je veux savoir pour lequel tous les identifiants d'employés l'appel a échoué.

+0

Quelle est l'erreur de compilation pour 'EitherT'? –

+0

@ZiyangLiu J'ai mis à jour l'erreur dans la question – arjunswaj

Répondre

0

EitherT prend un F[Either[A, B]] mais vous avez un Free[Program, Either[Error, Employee]], ce qui n'est pas compatible.

La solution pour créer un alias de type pour Free[Program, A]:

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

Puis faire getEmployee retour MyAlias[Either[Error, Employee]] et même pour getAddress.

+0

En fait, [voici l'essentiel] (https://gist.github.com/arjunswaj/4c3c7789ccdd9f832f2cf16690b57cbf) de ce que j'ai. Même avec Type Alias, la compréhension ne fonctionne pas car EitherT et Free ne peuvent pas être combinés. Je veux savoir comment gérer ça. – arjunswaj