2011-09-12 8 views
4

明らかにRangeには、Any型の値が含まれているかどうかをチェックするメソッドがあります。私はそれがSeqLikeからであることを理解しますが、いくつかの問題を引き起こします。例えばScala Range contains(elem:Any)メソッド

、iがjoda.DateTimeからの時間と一致した:ここ

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

d.hourOfDay()ためcontains(elem: Any)で、DateTime.Propertyを返すINTではないが、コードはまだコンパイル。そのような呼び出しをコンパイル時にチェックする方法はありますか?

答えて

6

あなたはpimpRange型より安全に含まれているメソッドを追加することができます。

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

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

インポート暗黙的にし、任意の範囲のインスタンスにsafeContainsを呼び出す:

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 
3

the scaladocs for Rangeに基づいて、使用できる優れたRangeメソッドがないようです。

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

独自の方法で行います:

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

これは事前ジェネリックいるJavaのequalsからホールドオーバのようだ、とあるが、あなたのオプションは

明示的な型シグネチャを使用しているようですこの事実がScalaにもたらす不都合の1つだけです。

+1

ええと...しかし、多分、そのようなメソッドへの呼び出しのためのコンパイラの警告があるはずです。このような実行時エラーが型保証された言語であることは間違っているようです。 – F0RR

+0

より良い/より良い警告を生成するプラグインが大好きです。そんなことはありますか? – ziggystar

+0

@ziggystar私はそれを認識していません。私はコンパイラがどのようにこれがあなたが望むものではないと言うことができるのかよくわかりません(適切な解決方法かもしれないが、他の問題があります...) – Owen

7

あなたがScalazのタイプセーフな等号を使用することができます(===TraversableOnceexistsメソッドと併用してください。

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" } 
          ^
関連する問題