O intervalo Scala contém (elem:Qualquer) método
Pergunta
Aparentemente Range
possui um método que verifica se contém um valor do tipo Any.Eu entendo que é de SeqLike
, mas causa alguns problemas.
Por exemplo, eu estava combinando horas de joda.DateTime:
DateTime.now match {
case d if 0 to 12 contains d.hourOfDay() => ...
Aqui d.hourOfDay() retorna DateTime.Property, não Int, mas o código ainda é compilado, por causa de contains(elem: Any)
.Existe alguma maneira de verificar essas chamadas em tempo de compilação?
Solução
Você pode cafetão Range
para adicionar um método contém com segurança de tipo:
class SafeRange( range: Range ) {
def safeContains( i: Int ) = range contains i
}
object SafeRange {
implicit def safer( range: Range ) = new SafeRange( range )
}
Importe o implícito e chame safeContains
em qualquer instância de intervalo:
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
Outras dicas
Você pode usar os equals typesafe do Scalaz (===
) em conjunto com o método exists
em 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" }
^
Baseado em os escaladocs para Range parece que não há um método Range melhor que você possa usar.Suas opções parecem ser
Use uma assinatura de tipo explícita:
case d if 0 to 12 contains (d.hourOfDay(): Int) => ...
Faça seu próprio método:
def containsInt(r: Range, i: Int) = ...
Este parece ser um resquício do Java equals
sendo pré-genéricos, e é apenas um dos inconvenientes que este fato causa ao Scala.