I am trying to convert a couple of Java enumerations values into another Java enumeration (the usage of Java enum over Scala Enumeration is due to legacy reasons - the enums are actually generated using JAXB).
Instead of a plain old pattern matching and having a map mapping one enumeration type to another, I figured writing a typeclass looks cleaner (also kinda cool). When I use simulacrum to do this, it compiles and runs just great. However, when I try to hand-code the typeclass myself, it throws a compilation error
[error] /Users/arun/IdeaProjects/AdvancedScala/src/main/scala/MultipleToSingleEnum.scala:32: value toEmail is not a member of TradeEnum
[error] println (TradeEnum.CLEARED.toEmail)
The code for the Java enumerations are :
Source enumerations
public enum TradeEnum {
CONFIRMED, CLEARED
}
public enum SeriesEnum {
CREATED,DELETED
}
Target enumeration
public enum EmailEnum {
T_CONFIRMED, T_CLEARED, S_CREATED, S_DELETED
}
Typeclass using Simulacrum (Works just fine !)
import simulacrum._
@typeclass trait EmailEnumConvertibleSim[A]{
def toEmailEnum(value:A):Option[EmailEnum]
}
object EmailEnumConvertibleSim{
implicit val tradeToEmailEnum = new EmailEnumConvertibleSim[TradeEnum]{
private val map=Map(
TradeEnum.CLEARED -> EmailEnum.T_CLEARED,
TradeEnum.CONFIRMED -> EmailEnum.T_CONFIRMED
)
override def toEmailEnum(value: TradeEnum): Option[EmailEnum] = map.get(value)
}
implicit val seriesToEmailEnum = new EmailEnumConvertibleSim[SeriesEnum]{
private val map=Map(
SeriesEnum.CREATED -> EmailEnum.S_CREATED,
SeriesEnum.DELETED -> EmailEnum.S_DELETED
)
override def toEmailEnum(value: SeriesEnum): Option[EmailEnum] = map.get(value)
}
}
import EmailEnumConvertibleSim.ops._
object MultipleToSingleEnumSim {
def main(args: Array[String]): Unit = {
println (TradeEnum.CLEARED.toEmailEnum)
}
}
Hand-coded type class (Ops)
trait EmailEnumConvertible[A]{
def toEmailEnum(value:A):Option[EmailEnum]
}
object EmailEnumConvertible{
implicit val tradeToEmailEnum = new EmailEnumConvertible[TradeEnum]{
private val map=Map(
TradeEnum.CLEARED -> EmailEnum.T_CLEARED,
TradeEnum.CONFIRMED -> EmailEnum.T_CONFIRMED
)
override def toEmailEnum(value: TradeEnum): Option[EmailEnum] = map.get(value)
}
}
object EmailEnumOps{
implicit class EmailEnumOps[A] (value:A){
def toEmail()(implicit emailConvertable:EmailEnumConvertible[A]):Option[EmailEnum]={
emailConvertable.toEmailEnum(value)
}
}
}
import EmailEnumOps._
object MultipleToSingleEnum {
def main(args: Array[String]): Unit = {
println (TradeEnum.CLEARED.toEmail) //ERROR IS REPORTED HERE !!
}
}
Any light on the error message is highly appreciated.