{"id":12064,"date":"2015-03-03T00:17:00","date_gmt":"2015-03-02T23:17:00","guid":{"rendered":"http:\/\/touk.pl\/blog\/?guid=4abeabd79e9520e9a1fc9d8d55be352c"},"modified":"2022-08-02T13:34:37","modified_gmt":"2022-08-02T11:34:37","slug":"enums-for-scala","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2015\/03\/03\/enums-for-scala\/","title":{"rendered":"Enums for scala"},"content":{"rendered":"<p>Scala has very limited implementation of Enumeration. Enumerated objects can&#8217;t extends other classes. Partial replacement for it is to use sealed classes. You can do pattern matching on them. When you ommit some possible value you will get compiler warning for not exhaustive pattern matching. One missing feature is that you can&#8217;t get sorted values of all objects extending them. You can simple got it using my (40-lines) EnumOf class from <a href=\"https:\/\/github.com\/arkadius\/scala-enum\">scala-enum<\/a>. Examples below.<\/p>\n<h3 id=\"declaration\">Declaration<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\">sealed abstract class Color(red: Double, green: Double, blue: Double)\r\n\r\nobject Color extends EnumOf[Color] {\r\n  case object Red   extends Color(1, 0, 0)\r\n  case object Green extends Color(0, 1, 0)\r\n  case object Blue  extends Color(0, 0, 1)\r\n  case object White extends Color(0, 0, 0)\r\n  case object Black extends Color(1, 1, 1)\r\n}<\/pre>\n<h3 id=\"usage\">Usage<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\">Color.values\u00a0shouldEqual\u00a0List(Red,\u00a0Green,\u00a0Blue,\u00a0White,\u00a0Black)\r\n\r\nColor.valueOfOpt(\"Blue\").value shouldEqual Blue\r\nColor.valueOfOpt(\"NotExisiting\").isEmpty shouldBe true<\/pre>\n<p>You can also enumerate on objects nested in instances<\/p>\n<h3 id=\"declaration-2\">Declaration<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">case class DistanceFrom(srcCity: String, srcCoordinates: Coordinate) extends EnumOf[DistanceBetween] {\r\n\r\n    case object ToBerlin extends DistanceFromSrcCityTo(\"Berlin\", Coordinate(52.5075419, 13.4251364))\r\n    case object ToNewYork extends DistanceFromSrcCityTo(\"New York\", Coordinate(40.7033127, -73.979681))\r\n    abstract class DistanceFromSrcCityTo(val destCity: String, val destCoordinates: Coordinate) extends DistanceBetween {\r\n        override def srcCoordinates: Coordinate = DistanceFrom.this.srcCoordinates\r\n    } \r\n}\r\n\r\nsealed abstract class DistanceBetween {\r\n    def srcCoordinates: Coordinate\r\n    def destCity: String\r\n    def destCoordinates: Coordinate\r\n    def inKm: Int = Coordinate.distanceInKm(srcCoordinates, destCoordinates).toInt\r\n}<\/pre>\n<h3 id=\"usage-2\">Usage<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">val DistanceFromWarsaw = DistanceFrom(\"Warsaw\", Coordinate(52.232938, 21.0611941))\r\nDistanceFromWarsaw.ToBerlin.inKm shouldEqual 519\r\nDistanceFromWarsaw.ToNewYork.inKm shouldEqual 6856\r\nDistanceFromWarsaw.values.map(_.inKm) shouldEqual List(519, 6856)<\/pre>\n","protected":false},"excerpt":{"rendered":"Scala has very limited implementation of Enumeration. Enumerated objects can&#8217;t extends other classes. Partial replacement for it is to use sealed classes. You can do  pattern matching on them. When you ommit some possible value you will get compiler wa&#8230;\n","protected":false},"author":28,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[296,113],"class_list":{"0":"post-12064","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design","7":"tag-github","8":"tag-scala"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12064","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=12064"}],"version-history":[{"count":4,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12064\/revisions"}],"predecessor-version":[{"id":14847,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12064\/revisions\/14847"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=12064"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=12064"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=12064"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}