简体   繁体   中英

Scala pattern match with type parameter of type class

sealed trait FormField
case class StringField(name: String, value: String) extends FormField
case class ChoiceField[T : Writes](name: String, value: T, choices: List[T]) extends FormField

and then, somewhere else I need to do this:

def makeJson(fields: List[FormField]) = fields.map {
   case StringField(name, value) => Json.obj(name -> value)
   case ChoiceField(name, value, _) => Json.obj(name -> value)
}

In that last function, scalac/sbt doesn't "understand" that value is convertable to json (through its implicit / type class Writes[T] ). How can I write it so that it "gets it"?

(Note: Writes[T] is from Play Framework - it basically says that there is an implicit conversion avaiable for the type T => JsValue )

Your problem is that the Writes implicit is not in scope when you do pattern matching; the easiest solution would be to keep an explicit reference to it so that you can use it when needed. That way your class definition becomes something like:

case class ChoiceField[T](name: String, value: T, choices: List[T])(implicit val writes: Writes[T]) extends FormField

And your pattern match:

case cf @ ChoiceField(name, value, _) =>
  implicit val tWrites = cf.writes
  Json.obj(name -> value)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM