Scala delay type

I am using Play framework 2.1 and Scala 2.10.1 and would like to build a generic function to build JsArray from a list of custom case class.

private def buildJsArray[T](l: List[T])(result: JsArray): JsArray = { l match { case List() => result case x::xs => buildJsArray(xs)(result :+ Json.toJson(x)) // compiling error here! } } 

using:

 val applyJsonArray = buildJsArray(List[Apple])(new JsArray()) 

However, a compilation error occurs:

 No Json deserializer found for type T. Try to implement an implicit Writes or Format for this type. 

I have a Json deserializer written for a specific case class (i.e. Apple Case class).

How to defer the compiler for checking type x at runtime, and not at compile time?

Thank you very much!

+6
source share
1 answer

How to fix the error

You must add an implicit parameter to your method as follows:

 def buildJsArray[T](l: List[T])(result: JsArray)(implicit tjs: Writes[T]): JsArray 

Json.toJson has such a parameter.

The reason you need to add this parameter is because you know how to convert T to json only when you know what T . This means that you have a way to serialize T only when calling buildJsArray , and this parameter allows you to pass this serialization method to the buildJsArray method.

How to create JSArray

You can just use the JsArray constructor. Seq[JsValue] :

 new JsArray(l.map{Json.toJson(_)}) 

Implicit Writes already exist for Traversable , so you don't need your own buildJsArray method, you could just use the Json.toJson method with a parameter of type List[T] .

Adding

You should look at the api collection. This allows you to write more readable and shorter code:

 def buildJsArray[T](l: List[T])(implicit tjs: Writes[T]): JsArray = l.foldLeft(new JsArray){ (r, x) => r :+ Json.toJson(x) } 
+15
source

Source: https://habr.com/ru/post/948033/


All Articles