Skip to content

Instantly share code, notes, and snippets.

@bvenners
Last active August 29, 2015 14:07
Show Gist options
  • Save bvenners/de2a55f749dda22cc622 to your computer and use it in GitHub Desktop.
Save bvenners/de2a55f749dda22cc622 to your computer and use it in GitHub Desktop.
Safe contains and *indexOf* methods for Seqs and Arrays in Scalactic 3.0
//
// This demos type errors for safe variants of contains, indexOf, lastIndexOf, indexOfSlice, and lastIndexOfSlice
// added to Scala Seqs and Arrays via an implicit conversion. These do rely on the trick of implicitly converting
// away the covariance of the type parameter, because in Scala 2.10 that is necessary. But in Scala 2.11, it is not
// necessary, because the compiler will disinguish beween implicits for covariant and invariant Seqs. Nevertheless
// I think provides value so I've done it this way by commenting out the implicit that doesn't work in 2.10:
//
// https://github.com/scalatest/scalatest/blob/master/src/main/scala/org/scalactic/SafeSeqs.scala#L25
//
// Someday when we drop support for Scala 2.10 I can uncomment that implicit and then this will no longer be
// relying on the "limitation" of type inference that enables covariance to be implicitly converted away.
//
// Scaladoc for SafeSeqs is here:
//
// http://www.artima.com/docs-scalatest-3.0.0-SNAP1/#org.scalactic.SafeSeqs
//
scala> import org.scalactic._
import org.scalactic._
scala> import SafeSeqs._
import SafeSeqs._
scala> List(1, 2, 3).contains(2)
res0: Boolean = true
scala> List(1, 2, 3).safeContains(2)
res1: Boolean = true
scala> List(1, 2, 3).contains("two")
res2: Boolean = false
scala> List(1, 2, 3).safeContains("two")
<console>:17: error: Cannot prove that String <:< Int.
List(1, 2, 3).safeContains("two")
^
scala> List(1, 2, 3).indexOf(2)
res4: Int = 1
scala> List(1, 2, 3).safeIndexOf(2)
res5: Int = 1
scala> List(1, 2, 3).indexOf("two")
res6: Int = -1
scala> List(1, 2, 3).safeIndexOf("two")
<console>:17: error: Cannot prove that String <:< Int.
List(1, 2, 3).safeIndexOf("two")
^
scala> List(1, 2, 3).lastIndexOf(2)
res8: Int = 1
scala> List(1, 2, 3).safeLastIndexOf(2)
res9: Int = 1
scala> List(1, 2, 3).lastIndexOf("two")
res10: Int = -1
scala> List(1, 2, 3).safeLastIndexOf("two")
<console>:17: error: Cannot prove that String <:< Int.
List(1, 2, 3).safeLastIndexOf("two")
^
scala> List(1, 2, 3).indexOfSlice(List(2, 3))
res12: Int = 1
scala> List(1, 2, 3).safeIndexOfSlice(List(2, 3))
res13: Int = 1
scala> List(1, 2, 3).indexOfSlice(List("two", "three"))
res14: Int = -1
scala> List(1, 2, 3).safeIndexOfSlice(List("two", "three"))
<console>:17: error: Cannot prove that String <:< Int.
List(1, 2, 3).safeIndexOfSlice(List("two", "three"))
^
scala> List(1, 2, 3).lastIndexOfSlice(List(2, 3))
res16: Int = 1
scala> List(1, 2, 3).safeLastIndexOfSlice(List(2, 3))
res17: Int = 1
scala> List(1, 2, 3).lastIndexOfSlice(List("two", "three"))
res18: Int = -1
scala> List(1, 2, 3).safeLastIndexOfSlice(List("two", "three"))
<console>:17: error: Cannot prove that String <:< Int.
List(1, 2, 3).safeLastIndexOfSlice(List("two", "three"))
^
// This is the build.sbt I used to generate the above REPL session. Just
// place this in a directory and say:
// $ sbt
// ...
// > console
scalaVersion := "2.11.2"
libraryDependencies += "org.scalactic" % "scalactic_2.11" % "3.0.0-SNAP1"
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "3.0.0-SNAP1" % "test"
initialCommands in console := "import org.scalactic._"
initialCommands in Test in console := """|import org.scalatest._
|import org.scalactic._
|import Matchers._""".stripMargin
resolvers += "Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment