A short way to create a list of days of the week in Scala

I am new to Scala, so please be kind. You must excuse me if I miss something obvious.

I am trying to create an enum like structure to represent the days of the week in Scala. I want a method that takes a string, which can be a number from 1 to 7, the full name of the day or an abbreviation of three letters with any capitalization and returns the correct day. Ideally, I want to get the correct day by simply writing DayOfWeek(_) , which, as I understand it, means that this method should be apply . Individual values ​​must also be subclassed (or mixed) by the CalendarField attribute, which currently does not define methods or members.

This is my current attempt:

 object DayOfWeek extends Enumeration with CalendarField { val Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday = Value def apply(v:String) = { v.toUpperCase match { case Int(x) => x match { case 1 => Sunday case 2 => Monday case 3 => Tuesday case 4 => Wednesday case 5 => Thursday case 6 => Friday case 7 => Saturday case _ => throw new IllegalArgumentException("Invalid value for day of week: " + v) } case "SUN" | "SUNDAY" => Sunday case "MON" | "MONDAY" => Monday case "TUE" | "TUEDAY" => Tuesday case "WED" | "WEDNESDAY" => Wednesday case "THU" | "THURSDAY" => Thursday case "FRI" | "FRIDAY" => Friday case "SAT" | "SATURDAY" => Saturday case _ => throw new IllegalArgumentException("Invalid value for day of week: " + v) } } } object Int { def unapply(s : String) : Option[Int] = try { Some(s.toInt) } catch { case _ : java.lang.NumberFormatException => None } } 

This does not work at several points:

  • Individual values ​​are not subclasses of CalendarField - they are simply Value s.
  • I defined an apply method, but DayOfWeek(_) does not work - my guess is (undefined) because it expects a constructor call, and DayOfWeek is an object, not a class? Or is it because Enumeration (s: String) is already in use? Is there any way around this?

Any suggestions on how to get around these problems or new solutions are welcome. Thanks.

+4
source share
3 answers

I would probably implement something like this:

 sealed trait DayOfWeek case object Monday extends DayOfWeek case object Tuesday extends DayOfWeek // etc. object DayOfWeek { def unapply(s: String): Option[DayOfWeek] = s.toUpperCase match { case Int(x) => x match { case 1 => Some(Sunday) // ... case _ => None } case "SUN" | "SUNDAY" => Some(Sunday) // ... case _ => None } def apply(s: String): DayOfWeek = s match { case DayOfWeek(d) => d case _ => throw new IllegalArgumentException( "Invalid value for day of week: " + s) } 

}

+6
source

Using case objects will solve problem 1, since case objects may have a common base class. Since this base class does not inherit from Enumeration , you will not have problems with inherited application methods. Here is a sample code:

 sealed abstract class DayOfWeek { def apply(s:String) = { //... } } case object Monday extends DayOfWeek case object Tuesday extends DayOfWeek //and so on... 
0
source
 object WeekEnumerator{ sealed trait Week object WeekDay extends Week object WeekEnd extends Week val sat, sun = WeekEnd val mon, tue, wed, thr, fri = WeekDay def isWorkingDay(day:WeekEnumerator.Week):Boolean = day match{ case day @ WeekEnd => false case day @ WeekDay => true } } 

Usage: WeekEnumerator.isWorkingDay (WeekEnumerator.sun)

0
source

All Articles