Scala Range contains a method (elem: Any)

Apparently Range has a method that checks to see if it contains a value of type Any. I understand that this is from SeqLike , but it causes some problems.

For example, I answered for hours with joda.DateTime:

 DateTime.now match { case d if 0 to 12 contains d.hourOfDay() => ... 

Here d.hourOfDay () returns DateTime.Property, not Int, but the code is still compiling due to contains(elem: Any) . Is there a way to check for such calls at compile time?

+4
source share
3 answers

You can Range pimp add a safer type method:

 class SafeRange( range: Range ) { def safeContains( i: Int ) = range contains i } object SafeRange { implicit def safer( range: Range ) = new SafeRange( range ) } 

Import implicit and call safeContains for any range instance:

 scala> import SafeRange._ import SafeRange._ scala> (0 until 10) safeContains 3 res2: Boolean = true scala> (0 until 10) safeContains 100 res3: Boolean = false scala> (0 until 10) safeContains "foo" <console>:18: error: type mismatch; found : java.lang.String("foo") required: Int (0 until 10) safeContains 
+6
source

In the exists method of TraversableOnce you can use values โ€‹โ€‹of Scala types ( === ).

 scala> import scalaz._ import scalaz._ scala> import Scalaz._ import Scalaz._ scala> 1 to 5 exists { _ === 2 } res1: Boolean = true scala> 1 to 5 exists { _ === "Hullo" } <console>:14: error: type mismatch; found : java.lang.String("Hullo") required: Int 1 to 5 exists { _ === "Hullo" } ^ 
+7
source

Based on scaladocs for Range, it looks like the best Range method you can't use. Your options look like

Use an explicit type signature:

  case d if 0 to 12 contains (d.hourOfDay(): Int) => ... 

Make your own method:

  def containsInt(r: Range, i: Int) = ... 

Preserving Java equals seems to be pre-generic and is just one of the inconveniences this fact causes for Scala.

+3
source

All Articles