I have a case class defined for JSON parsing using the Circe library:
final case class Event(
source: Option[String],
nonce: Option[Int],
`type`: Option[Any],
tag: Option[String],
payload: Option[Any],
blockOrder: Option[Int] = None,
metadata: ResultMetadata[OperationResult.Event]
) extends Operation
Note that one of the fields is called type
and I can only use the name using backticks or I get a compiler error. I don't have any choice over the schema used by the source system supplying the data.
Later on, when I try to pattern match on the case class in order to write some information to a database...
private val convertEvent: PartialFunction[
(Block, OperationHash, Operation),
Tables.OperationsRow
] = {
case (
block,
groupHash,
Event(source, nonce, `type`, tag, payload, blockOrder, metadata)
) =>
...
...I get the following error:
not found: value type
Event(source, nonce, `type`, tag, payload, blockOrder, metadata).
Is there any way I can still use Circe and case classes in general when a field has the same name as a reserved keyword?
CodePudding user response:
In 2.13.8 the error is
not found: value type
Identifiers enclosed in backticks are not pattern variables but match the value in scope.
Event(source, nonce, `type`, tag, payload, blockOrder, metadata)
so just use something different from type
in pattern matching as a pattern variable.
For example
case (
block,
groupHash,
Event(source, nonce, typ, tag, payload, blockOrder, metadata)
) =>
CodePudding user response:
That's because backticks in pattern matching mean to use an already-existing value accessible in the scope, to check the equity of a pattern variable, like this:
case class Person(name: String, age: Int)
val johnName = "John"
val john = Person(johnName, 99)
val alice = Person("Alice", 128)
john match {
case Person(`johnName`, someAge) =>
// this will be matched, sine johnName = "John"
}
alice match {
case Person(`johnName`, someAge) =>
// won't match, "Alice" != "John"
case Person(johnName, someAge) =>
// this one matches, since johnName in the pattern is only some alias,
// and will shadow the variable defined above
}
The solution/workaround is already mentioned in the other anwer.