2014-06-11 1 views
0

Je construis une petite bibliothèque en ajoutant une classe de type pour sérialiser et désérialiser. J'ai créé un implicite qui enveloppe le résultat autour d'une validation scalaz mais délègue le reste à un autre implicite (code ci-dessous). Ma question est, dans Serialize, il y a le validateSer qui prend un Serialize [A, B] et renvoie Serialize [A, Validation [Throwable, B]]. Cela fonctionne très bien, mais quand je fais la même chose pour Deserialize, le compilateur ne peut pas comprendre lequel implicite à utiliser. Comment puis-je faire fonctionner ceci à la fois sérialiser et désérialiser?Implicite avec le type plus spécifique ne pas être ramassé

sérialisation

trait Serialize[A, B] { 
    def serialize(a: A): B 
} 

object Serialize { 

    import [email protected]@ 
    import Format._ 

    implicit def validateSer[A, B](implicit ser: Serialize[A, B]): Serialize[A, Validation[Throwable, B]] = 
    new Serialize[A, Validation[Throwable, B]] { 
     override def serialize(t: A): Validation[Throwable, B] = 
     Validation.fromTryCatch(ser.serialize(t)) 
    } 

    implicit def jsonSerString[A]: Serialize[A, String @@ JSON] = new Serialize[A, String @@ JSON] { 
    override def serialize(t: A): String @@ JSON = 
     JSON(mapper.writeValueAsString(t)) 
} 

object HardTypeForJackson 
HardTypeForJackson.serialize[Validation[Throwable, String @@ JSON]] // works 

Deserialize

trait Deserialize[A, B] { 
    def deserialize(a: A): B 
} 

object Deserialize { 
    import [email protected]@ 
    import Format._ 

    implicit def validateDes[A, B](implicit des: Deserialize[A, B]): Deserialize[A, Validation[Throwable, B]] = 
    new Deserialize[A, Validation[Throwable, B]] { 
     override def deserialize(a: A): Validation[Throwable, B] = 
     Validation.fromTryCatch(des.deserialize(a)) 
    } 

    implicit def jsonDesString[B: Manifest]: Deserialize[String @@ JSON, B] = new Deserialize[String @@ JSON, B] { 
    override def deserialize(a: String @@ JSON): B = 
     mapper.readValue[B](a) 
} 

JSON("foo").deserialize[Validation[Throwable, PuppetCommand]] // compiler error 

    Error:(82, 41) ambiguous implicit values: 
both method validateDes in trait DeserializeInstances of type [A, B](implicit des: com.gopivotal.heimdall.util.Deserialize[A,B])com.gopivotal.heimdall.util.Deserialize[A,scalaz.Validation[Throwable,B]] 
and method jsonDesString in trait DeserializeInstances of type [B](implicit evidence$1: Manifest[B])com.gopivotal.heimdall.util.Deserialize[[email protected]@[String,com.gopivotal.heimdall.util.Format.JSON],B] 
match expected type com.gopivotal.heimdall.util.Deserialize[[email protected]@[String,com.gopivotal.heimdall.util.Format.JSON],scalaz.Validation[Throwable,com.gopivotal.heimdall.orchestration.PuppetCommand]] 
    val parsed = JSON("foo").deserialize[Validation[Throwable, PuppetCommand]] 

Répondre

0

Ok, le code que je mets ci-dessus est pas ce que j'utilisais. J'ai tous les implicits dans un trait appelé DeserializeInstances et l'objet Deserialize vient de l'étendre. Quand je déplace la validation implicite dans l'objet plutôt que dans le trait, alors il est pris comme prévu.

Questions connexes