Scala类型签名与子类一起失败

Scala类型签名与子类一起失败,scala,scalaz,Scala,Scalaz,我已定义以下异常层次结构: /** * 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(mes

我已定义以下异常层次结构:

/**
  * 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
以及以下代码:

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
    返回
    ValidationNel[PersistenceException,String]
  • contactForm.validate()
    返回
    ValidationNel[字符串,布尔值]

问题是
handleForm
不接受
PersistenceException
ValidationException
MyAkkaHttpException
的子类。我需要做什么才能正确认识到这些返回类型是有效的子类?

尝试将
ValidationNel[myakkahtpexception,String]
更改为
Validation[NonEmptyList[myakkahtpexception],String]
。正如有人在评论中指出的,只有类型别名在第一个类型参数中是不协变的

type ValidationNel[E, +X] = Validation[NonEmptyList[E], X]
否则,
NonEmptyList
Validation
在所有参数中都是协变的

编辑:
这可能取决于您的
scalaz
版本。就我可以浏览的最新版本而言,它看起来像是
ValidationNel
,但是。这种更改可能有一个很好的理由:准备好不能将Scalaz的函数用于
ValidationNel

问题是您需要
ValidationNel
的第一个类型参数的协方差,而
Validation
的这个特殊快捷方式并没有考虑到这种协方差*

根据我从我们的评论交流中收集的信息,我认为这是正确的前进方向。声明您自己的别名(或直接使用该类型)


*)然而,我确实有一种感觉,在
E
参数上没有协方差是有原因的(因为scalaz通常知道做事情是有原因的)

左右两边都是协方差的,所以我只是切换到了这一点。

使用
+
,我相信。@Elazar我试过了,但它显示为语法错误。请您写一个答案好吗?请尝试
ValidationNel[+myakkahttppeexception,String]
@Elazar,它给出了这个错误:
error:(17,87)应该是标识符,但找到了。def handleForm(contactForm:contactForm):ValidationNel[+MyakkahtpeException,String]={
别名为
ValidationNel[E,+X]=Validation[NonEmptyList[E],X]
,在第一个参数上需要共变。尝试使用
Validation[+T1,T2]
Validation[NonEmptyList[+E],X]
-但在
E
type MyValidationNel[+E, +X] = Validation[NonEmptyList[E], X]