Home > Enterprise >  Pattern matching for headOption with enum
Pattern matching for headOption with enum

Time:05-08

The problem I'm trying to solve is to check if the first element (if any) of a list is of a certain enum type. As follows:

enum Color(val rgb: Int):
  case Red   extends Color(0xFF0000)
  case Green extends Color(0x00FF00)
  case Blue  extends Color(0x0000FF)
  case CustomColor(override val rgb: Int) extends Color(rgb)



def isExpected(expect: Color, colors: List[Color]): Either[Error, (Color, List[Color])] =
  colors.headOption match {
    case Some(head) => {
      if (head == expect) { Right(expect, tokens.tail) }
      else {
        expect match {
          case Color.Red => Left(Error.ExpectRed)
          case Color.Green => Left(Error.ExpectGreen)
          case Color.Blue => Left(Error.ExpectBlue)
        }
      } 
    }
    case _ => {
      expect match {
          case Color.Red => Left(Error.ExpectRed)
          case Color.Green => Left(Error.ExpectGreen)
          case Color.Blue => Left(Error.ExpectBlue)
      }
    }
  }
  1. Is there a way to refactor the duplicated code in the above snippet?
  2. Is it possible to check if the type of headOption matches the expect parameter even in the first case condition?

CodePudding user response:

How about this:

scala> enum Color(val rgb: Int):
     |   case Red   extends Color(0xFF0000)
     |   case Green extends Color(0x00FF00)
     |   case Blue  extends Color(0x0000FF)
     |   case CustomColor(override val rgb: Int) extends Color(rgb)
     |
     | enum Error:
     |   case ExpectRed
     |   case ExpectGreen
     |   case ExpectBlue
     |   case ExpectCustom
     |
     |
     | def isExpected(expect: Color, colors: List[Color]): Either[Error, (Color, List[Color])] = colors match
     |   case `expect` :: tail => Right(expect, tail)
     |   case _                =>
     |     expect match
     |       case c: Color.CustomColor => Left(Error.ExpectCustom)
     |       case rgb                  => Left(Error.valueOf(s"Expect$rgb"))
     |
// defined class Color
// defined class Error
def isExpected
  (expect: Color, colors: List[Color]): Either[Error, (Color, List[Color])]

scala> val colors = List(Color.Red, Color.Green, Color.CustomColor(123))
val colors: List[Color] = List(Red, Green, CustomColor(123))

scala> isExpected(Color.Green, colors)
val res0: Either[Error, (Color, List[Color])] = Left(ExpectGreen)

scala> isExpected(Color.Red, colors)
val res1: Either[Error, (Color, List[Color])] = Right((Red,List(Green, CustomColor(123))))

scala> isExpected(Color.CustomColor(123), colors)
val res2: Either[Error, (Color, List[Color])] = Left(ExpectCustom)
  • Related