Skip to content

Instantly share code, notes, and snippets.

@bvenners
Last active August 29, 2015 14:08
Show Gist options
  • Save bvenners/8eec1cd4eb632de61e4a to your computer and use it in GitHub Desktop.
Save bvenners/8eec1cd4eb632de61e4a to your computer and use it in GitHub Desktop.
Using EquaSets in methods, take 2
// This is from github ScalaTest master, not in any release:
// Here's a method that takes a general one. This method asks the passed EquaSet
// for its enclosing EquaSets, and stores it in variable path. It then "copies"
// the passed EquaSet into the new path, after which it can union with a newly
// created EquaSet at the same path and return it.
scala> def addBippy(set: EquaSets[String]#EquaSet): EquaSets[String]#EquaSet = {
| val path = set.enclosingEquaSets
| val relocated = set.copyInto(path)
| relocated union path.EquaSet("bippy")
| }
addBippy: (set: org.scalactic.EquaSets[String]#EquaSet)org.scalactic.EquaSets[String]#EquaSet
// Two EquaSets, not in scope in the above method
scala> val lowered = SortedEquaSets[String](StringNormalizations.lowerCased.toOrderingEquality)
lowered: org.scalactic.SortedEquaSets[String] = org.scalactic.SortedEquaSets@76640885
scala> val trimmed = EquaSets[String](StringNormalizations.trimmed.toHashingEquality)
trimmed: org.scalactic.EquaSets[String] = org.scalactic.EquaSets@f4080ae
// Can pass either kind to the method, because it is general
scala> val lowBip = addBippy(lowered.EquaSet("Hi"))
lowBip: org.scalactic.EquaSets[String]#EquaSet = EquaSet(Hi, bippy)
scala> val trimBip = addBippy(trimmed.EquaSet("Hi"))
trimBip: org.scalactic.EquaSets[String]#EquaSet = EquaSet(Hi, bippy)
// Can't union the returned value, because it too is general
scala> lowBip union lowered.EquaSet("ug")
<console>:20: error: type mismatch;
found : lowered.EquaSet
required: _8.EquaSet where val _8: org.scalactic.EquaSets[String]
lowBip union lowered.EquaSet("ug")
^
// But once "copied" into the desired path, it can be unioned
scala> lowBip.copyInto(lowered) union lowered.EquaSet("ug")
res3: lowered.EquaSet = EquaSet(Hi, bippy, ug)
// The reason I put copied in scare quotes is that copyInto has an optimization
// that if it is the same instance, it just casts it to the new type. So it is
// really relocating the same object to the new path.
scala> lowBip eq lowBip.copyInto(lowered)
res4: Boolean = true
scala> trimBip.copyInto(lowered) union trimmed.EquaSet("ug")
<console>:21: error: type mismatch;
found : trimmed.EquaSet
required: lowered.EquaSet
trimBip.copyInto(lowered) union trimmed.EquaSet("ug")
^
// Can do the same stuff with trimmed
scala> trimBip.copyInto(trimmed) union trimmed.EquaSet("ug")
res6: trimmed.EquaSet = EquaSet(Hi, bippy, ug)
scala> trimBip eq trimBip.copyInto(trimmed)
res7: Boolean = true
// Can also copy into a different path, in which case it is of course
// a real copy--i.e., a new EquaSet instance
scala> trimBip eq trimBip.copyInto(lowered)
res8: Boolean = false
scala> trimBip.copyInto(lowered) union lowered.EquaSet("ug")
res9: lowered.EquaSet = EquaSet(Hi, bippy, ug)
// And you still get the desired type errors if you try to mix notions
// of equality used to determine set membership
scala> trimBip.copyInto(lowered) union trimmed.EquaSet("ug")
<console>:21: error: type mismatch;
found : trimmed.EquaSet
required: lowered.EquaSet
trimBip.copyInto(lowered) union trimmed.EquaSet("ug")
^
// I made enclosingEquaSets a stable identifier so you could do the following.
// I think I'll just rename enclosingEquaSets to path to make this kind
// of usage more concise.
scala> def addBoppy(set: EquaSets[String]#EquaSet): EquaSets[String]#EquaSet = {
| val relocated = set.copyInto(set.enclosingEquaSets)
| relocated union set.enclosingEquaSets.EquaSet("bippy")
| }
addBoppy: (set: org.scalactic.EquaSets[String]#EquaSet)org.scalactic.EquaSets[String]#EquaSet
// I believe this is the approach you were talking about. That's actually pretty
// clean looking. I think I can explain it in examples:
scala> def addBeppy(sets: EquaSets[String])(set: sets.EquaSet): sets.EquaSet = {
| set union sets.EquaSet("bippy")
| }
addBoppy: (sets: org.scalactic.EquaSets[String])(set: sets.EquaSet)sets.EquaSet
scala> lowered.EquaSet("hi") union addBeppy(lowered)(lowered.EquaSet("ha"))
res14: lowered.EquaSet = EquaSet(hi, ha, bippy)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment