Created
January 17, 2014 17:47
-
-
Save bvenners/8477980 to your computer and use it in GitHub Desktop.
Applying ScalaUtils' tunable type checks to contains checking of Seqs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// If you paste this code into the Scala interpretter with ScalaUtils on the path: | |
List(1) contains 1 | |
List(1) contains "1" | |
import scala.collection.GenSeq | |
implicit class Containz[A](xs: GenSeq[A]) { | |
def containz[B <: A](ele: B): Boolean = xs.exists(_ == ele) | |
} | |
List(1) containz 1 | |
// This now gives the desired type error | |
List(1) containz "1" | |
List(List(1)) contains Vector(1) | |
// But this gives an undesired type error | |
List(List(1)) containz Vector(1) | |
// So will need to use an implicit constraint instead | |
import org.scalautils._ | |
import TypeCheckedTripleEquals._ | |
import TraversableEqualityConstraints._ | |
implicit class Containz[A](xs: GenSeq[A]) { | |
def containz[B](ele: B)(implicit ev: Constraint[A, B]): Boolean = xs.exists(ev.areEqual(_, ele)) | |
} | |
// Now the compiler allows this, as desired | |
List(1) containz 1 | |
// This fails to compile, as desired | |
List(1) containz "1" | |
// But the compiler also allows this, as desired | |
List(List(1)) containz Vector(1) | |
// It won't allow this to compile, which is "desired" because it returns true: | |
List(1) containz BigInt(1) | |
// But I can get that to work another implicit constraint, which I'll likely | |
// add to ScalaUtils now that I am aware of this cooperative | |
// equality behavior among Numeric types. | |
You will see this output: | |
scala> List(1) contains 1 | |
res0: Boolean = true | |
scala> List(1) contains "1" | |
res1: Boolean = false | |
scala> | |
scala> import scala.collection.GenSeq | |
import scala.collection.GenSeq | |
scala> implicit class Containz[A](xs: GenSeq[A]) { | |
| def containz[B <: A](ele: B): Boolean = xs.exists(_ == ele) | |
| } | |
defined class Containz | |
scala> | |
scala> List(1) containz 1 | |
res2: Boolean = true | |
scala> // This now gives the desired type error | |
scala> List(1) containz "1" | |
<console>:10: error: inferred type arguments [String] do not conform to method containz's type parameter bounds [B <: Int] | |
List(1) containz "1" | |
^ | |
<console>:10: error: type mismatch; | |
found : String("1") | |
required: B | |
List(1) containz "1" | |
^ | |
scala> | |
scala> List(List(1)) contains Vector(1) | |
res4: Boolean = true | |
scala> // But this gives an undesired type error | |
scala> List(List(1)) containz Vector(1) | |
<console>:10: error: inferred type arguments [scala.collection.immutable.Vector[Int]] do not conform to method containz's type parameter bounds [B <: List[Int]] | |
List(List(1)) containz Vector(1) | |
^ | |
<console>:10: error: type mismatch; | |
found : scala.collection.immutable.Vector[Int] | |
required: B | |
List(List(1)) containz Vector(1) | |
^ | |
scala> | |
scala> // So will need to use an implicit constraint instead | |
scala> import org.scalautils._ | |
import org.scalautils._ | |
scala> import TypeCheckedTripleEquals._ | |
import TypeCheckedTripleEquals._ | |
scala> import TraversableEqualityConstraints._ | |
import TraversableEqualityConstraints._ | |
scala> | |
scala> implicit class Containz[A](xs: GenSeq[A]) { | |
| def containz[B](ele: B)(implicit ev: Constraint[A, B]): Boolean = xs.exists(ev.areEqual(_, ele)) | |
| } | |
defined class Containz | |
scala> | |
scala> // Now the compiler allows this, as desired | |
scala> List(1) containz 1 | |
res6: Boolean = true | |
scala> | |
scala> // This fails to compile, as desired | |
scala> List(1) containz "1" | |
<console>:20: error: types Int and String do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalautils.Constraint[Int,String] | |
List(1) containz "1" | |
^ | |
scala> | |
scala> // But the compiler also allows this, as desired | |
scala> List(List(1)) containz Vector(1) | |
res8: Boolean = true | |
scala> | |
scala> // It won't allow this to compile, which is "desired" because it returns true: | |
scala> List(1) containz BigInt(1) | |
<console>:20: error: types Int and scala.math.BigInt do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalautils.Constraint[Int,scala.math.BigInt] | |
List(1) containz BigInt(1) | |
^ | |
scala> | |
scala> // But I can get that to work another implicit constraint, which I'll likely | |
scala> // add to ScalaUtils now that I am aware of this cooperative | |
scala> // equality behavior among Numeric types. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment