How to compose prameterized-types in scalaz validation?

107 views Asked by At

I've got some code like this:

import scalaz._, Scalaz._

case class Cat(
                      val lang: String,
                      val title: String,
                      val icon: String,
                      val count: Int,
                      val id: Option[Long])

case class InvalidDataException[T](
                                     msg:String,
                                     val value:T,
                                     cause:Option[Throwable] = None )
   extends Exception ( msg, cause getOrElse null )

trait CategoryService {

   private type NotEmptyErrorList = NonEmptyList[InvalidDataException[_]]
   private type _Validation = Validation[NotEmptyErrorList,Category]

   def createCategory(
                        lang: String,
                        title: String,
                        icon: String,
                        channels:String,
                        channelCount:Int = 0)(
                        implicit availableLangs: List[String],
                        session: SQLSession): _Validation = {

      val _tLang = lang.trim
      val _lang = if( !availableLangs.contains(_tLang) )
         InvalidDataException(s"Lang is invalid: ${lang}", lang).failureNel
      else _tLang.successNel

      val _tTitle = title.trim
      val _title = if( _tTitle.isEmpty )
         InvalidDataException("Title can't be empty", title ).failureNel
      else _tTitle.successNel

      val _tIcon = icon.trim
      val _icon = if( _tIcon.isEmpty )
         InvalidDataException("Icon is empty", icon).failureNel
      else _tIcon.successNel

      val _count = if( channelCount < 0 )
         InvalidDataException(s"Invalid Count for channels: ${channelCount}", channelCount).failureNel
      else channelCount.successNel

      ( _lang |@| _title |@| _icon |@| _count ) { (lang, title, icon, count) =>
         Cat(lang, title, icon, count, none)
      }
   }

}

When I try to compile this code, I get this error:

[error] ~/i/prjs/.../Cat.scala:62: type mismatch;
[error]  found   : scalaz.Validation[scalaz.NonEmptyList[InvalidDataException[Int]],Int]
[error]  required: scalaz.Validation[scalaz.NonEmptyList[InvalidDataException[String]],?]
[error]       ( _lang |@| _title |@| _icon |@| _count ) { (lang, title, icon, count) =>
[error]                                        ^

I know I can cast type to Any - mannually :

private type _V[T] = Validation[NotEmptyErrorList,T]
...
val _lang:_V[String] = ...

But I prefer compiler do this for me! Is there another way to pass the error? Why compiler can't cast those ?

0

There are 0 answers