2016-07-22 2 views
2

je la hiérarchie des exceptions suivantes définies:signature de type Scala échoue avec les sous-classes

/** 
    * Base class for all exceptions in this library 
    */ 
trait MyAkkaHttpException {} 

/** 
    * Thrown when there is a problem persisting data to a datastore 
    */ 
case class PersistenceException(message: String) 
    extends Exception(message: String) with MyAkkaHttpException 

/** 
    * Thrown when validation on an object fails 
    * @param errors 
    */ 
case class ValidationException(message: String, errors: List[String]) 
    extends Exception(message: String) with MyAkkaHttpException 

Et le code suivant:

class ContactFormService(contactFormPersistor: ContactFormPersistor) { 

    def handleForm(contactForm: ContactForm): ValidationNel[MyAkkaHttpException, String] = { 

    contactForm.validate() match { 
     case Success(_) => contactFormPersistor.persist(contactForm) 
     case Failure(e) => 
     new ValidationException(message = "Error validating contact form", 
      errors = e.toList).failureNel[String] 
    } 
    } 
} 
  • contactFormPersistor.persist retours ValidationNel[PersistenceException, String]
  • contactForm.validate() retours ValidationNel[String, Boolean]

Le problème est handleForm n'acceptera pas que PersistenceException et ValidationException sont des sous-classes de MyAkkaHttpException. Que dois-je faire pour réaliser correctement que ces types de retour sont des sous-classes valides?

+0

Utilisez '+', je crois. – Elazar

+0

@Elazar J'ai essayé mais ça se voit comme une erreur de syntaxe. S'il vous plaît pouvez-vous écrire une réponse? – jbrown

+0

try 'ValidationNel [+ MyAkkaHttpException, String]' – Elazar

Répondre

2

Essayez de remplacer ValidationNel[MyAkkaHttpException, String] par Validation[NonEmptyList[MyAkkaHttpException], String]. Comme quelqu'un l'a souligné dans les commentaires, c'est seulement l'alias de type qui n'est pas covariant dans l'argument du premier type.

type ValidationNel[E, +X] = Validation[NonEmptyList[E], X] 

Sinon, NonEmptyList et Validation sont tous les deux covariant dans tous leurs arguments.

EDIT:

Cela pourrait dépendre de votre version de scalaz. En ce qui concerne le dernier disponible que je peux parcourir, il ressemble à ValidationNelis no longer covariant in both arguments, mais it previously was. Il y a probablement une bonne raison à ce changement: soyez prêt à ne pas pouvoir utiliser les fonctions de Scalaz pour ValidationNel.

0

Le problème est que vous devez covariance sur le premier paramètre de type de ValidationNel et ce raccourci particulier de Validation n'a pas été conçu avec cette covariance à l'esprit *

D'après les informations i proviennent de nos échanges de commentaires, je crois que ce est la bonne marche à suivre. Déclarer votre alias (ou utilisez directement le type) Cependant, je ne

type MyValidationNel[+E, +X] = Validation[NonEmptyList[E], X] 

*) ai le sentiment qu'il y avait une raison derrière ne sait pas avoir covariance sur le E param (comme scalaz normalement faire des choses avec une raison)

0

Either est covariant à la fois sur la gauche et la droite, donc je viens de passer à cela à la place.