简体   繁体   中英

Scala Range contains(elem: Any) method

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

For instance, i was matching hours from joda.DateTime:

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

Here d.hourOfDay() returns DateTime.Property, not Int, but code still compiles, because of contains(elem: Any) . Is there any way to check for such calls at compile time?

You can use Scalaz's typesafe equals ( === ) in conjunction with exists method on TraversableOnce .

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" }
                             ^

You can pimp Range to add a type-safer contains method:

class SafeRange( range: Range ) {
  def safeContains( i: Int ) = range contains i
}

object SafeRange {
  implicit def safer( range: Range ) = new SafeRange( range )
}

Import the implicit and call safeContains on 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

Based on the scaladocs for Range it looks like there's not a better Range method you could use. Your options seem to be

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) = ...

This seems to be a holdover from Java equals being pre-generics, and is only one of the inconveniences this fact causes for Scala.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM