Created
October 22, 2014 19:51
-
-
Save bvenners/c5efdfe168305e26f208 to your computer and use it in GitHub Desktop.
Using EquaSets passed to methods
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
// | |
// This gist shows how the compiler will deal with EquaSets as method parameters. | |
// In short, the compiler will let you do anything that is known to be OK. In | |
// particular, it won't let you union, intersect, or diff two EquaSets unless | |
// the full path dependent type is known and matches. | |
// | |
scala> import org.scalactic._ | |
scala> val trimmed = EquaSets[String](StringNormalizations.trimmed.toHashingEquality) | |
trimmed: org.scalactic.EquaSets[String] = org.scalactic.EquaSets@2c011b16 | |
scala> val lowered = SortedEquaSets[String](StringNormalizations.lowerCased.toOrderingEquality) | |
lowered: org.scalactic.SortedEquaSets[String] = org.scalactic.SortedEquaSets@3b2d73bb | |
// If I take explicit paths, it won't let me union in the body, which is what we'd want | |
scala> def takesSets(tset: trimmed.EquaSet, wset: lowered.EquaSet) = tset union wset | |
<console>:12: error: type mismatch; | |
found : lowered.EquaSet | |
required: trimmed.EquaSet | |
def takesSets(tset: trimmed.EquaSet, wset: lowered.EquaSet) = tset union wset | |
^ | |
// But it will let me do something like call size, which is also what we want | |
scala> def takesSets(tset: trimmed.EquaSet, wset: lowered.EquaSet) = tset.size + wset.size | |
takesSets: (tset: trimmed.EquaSet, wset: lowered.EquaSet)Int | |
scala> takesSets(trimmed.EquaSet("hi"), lowered.SortedEquaSet("ho")) | |
res0: Int = 2 | |
// It won't let me pass the wrong path in, which is what we'd want | |
scala> takesSets(trimmed.EquaSet("hi"), trimmed.EquaSet("ho")) | |
<console>:14: error: type mismatch; | |
found : trimmed.EquaSet | |
required: lowered.EquaSet | |
takesSets(trimmed.EquaSet("hi"), trimmed.EquaSet("ho")) | |
^ | |
// It will let me any kind of EquaSet, and let me do things like call size on it, which | |
// is again what we'd ant | |
scala> def takesSets(tset: EquaSets[String]#EquaSet, wset: EquaSets[String]#EquaSet) = tset.size + wset.size | |
takesSets: (tset: org.scalactic.EquaSets[String]#EquaSet, wset: org.scalactic.EquaSets[String]#EquaSet)Int | |
// But it won't let me union, which is also what we want, because union requires more information than | |
// we have in these types. The error message is a bit non-obvious though. | |
scala> def takesSets(tset: EquaSets[String]#EquaSet, wset: EquaSets[String]#EquaSet) = tset union wset | |
<console>:10: error: type mismatch; | |
found : org.scalactic.EquaSets[String]#EquaSet | |
required: _10.EquaSet where val _10: org.scalactic.EquaSets[String] | |
def takesSets(tset: EquaSets[String]#EquaSet, wset: EquaSets[String]#EquaSet) = tset union wset | |
^ | |
// 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