-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add SortedMap
and SortedSet
instances/Move Set
and Map
instances to Alleycats
#1972
Conversation
else fb.map(fb => map2(fa, fb)(f)) | ||
|
||
override def ap[A, B](ff: SortedMap[K, A => B])(fa: SortedMap[K, A]): SortedMap[K, B] = | ||
??? //fa.flatMap { case (k, a) => ff.get(k).map(f => (k, f(a))) }(scala.collection.breakOut) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still WIP? same below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sorry. I meant to state so in the description 😅
df28b39
to
24fb152
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added #1973 about my doubts.
var a, b, n = 0 | ||
var c = 1; | ||
x foreach { case (k, v) => | ||
// use the default hash on keys because that's what Scala's Map does |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we want to do that here actually. Map[K, V]
needs to do this because the hash in question in a Map[K, V]
is the .hashCode
. But I think we can be unconstrained on a SortedMap
since it is only using our Order typeclass.
fa.foldLeft(b) { case (x, (k, a)) => f(x, a)} | ||
|
||
def foldRight[A, B](fa: SortedMap[K, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = | ||
Foldable.iterateRight(fa.values.iterator, lb)(f) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought this was actually unsafe since it captures a mutable iterator? I think to make it safe, it needs to have () => Iterator[A]
which it can call to get a new one each time (which is another way of saying the Iterable[A]
and it calls .iterator
internally.
We had some bug related to this in the past. Not sure why we didn't fix Foldable.iterateRight
. Actually, it was related, but not exactly the same. See #1716.
24fb152
to
5ec40c9
Compare
5ec40c9
to
a1705a9
Compare
Codecov Report
@@ Coverage Diff @@
## master #1972 +/- ##
==========================================
- Coverage 95.49% 95.24% -0.25%
==========================================
Files 298 301 +3
Lines 4814 4922 +108
Branches 120 123 +3
==========================================
+ Hits 4597 4688 +91
- Misses 217 234 +17
Continue to review full report at Codecov.
|
Damn there's no mutable |
035461b
to
c226af6
Compare
c226af6
to
26c1d9a
Compare
So the tests fail for 2.11 and earlier for some reason. Will have to investigate |
26c1d9a
to
9c76d12
Compare
9c76d12
to
62ec8d4
Compare
58e6907
to
fb37bba
Compare
fb37bba
to
a5948aa
Compare
…into LukaJCB-add-sorted-instances
@@ -218,14 +218,6 @@ class FoldableSuiteAdditional extends CatsSuite { | |||
checkFoldMStackSafety[Vector](_.toVector) | |||
} | |||
|
|||
test("Foldable[Set].foldM stack safety") { | |||
checkFoldMStackSafety[Set](_.toSet) | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we replace these two foldMStackSafety tests with SortedSet and SortedMap ones?
@@ -30,7 +30,7 @@ class ParallelTests extends CatsSuite with ApplicativeErrorForEitherTest { | |||
} | |||
|
|||
test("ParTraverse_ identity should be equivalent to parSequence_") { | |||
forAll { es: Set[Either[String, Int]] => | |||
forAll { es: List[Either[String, Int]] => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use SortedSet
? (Either
has Order
instance)
type StringMap[A] = Map[String, A] | ||
val intMap: StringMap[Int] = Map("one" -> 1, "two" -> 2, "six" -> 6, "eight" -> 8) | ||
intMap.traverse(validate) should === (Either.left("6 is greater than 5")) | ||
checkAndResetCount(3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what this regression test is about, do you know? If neither of us are sure maybe we should replace it with a sortedMap one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently it's about #513. I had to adjust this test slightly, because the order of the Strings matter now, so it wouldn't work if we just change the type of the collection :)
Everything should be addressed now 🎉 Thanks everyone! |
implicit def catsStdInstancesForMap[K]: Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] = | ||
new Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] { | ||
|
||
def traverse[G[_], A, B](fa: Map[K, A])(f: A => G[B])(implicit G: Applicative[G]): G[Map[K, B]] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add some law that this violates? I hate to remove it if we don’t actually have a law that it violates. I think we can write some (the original ticket had an example). I fear we could have other lawless instances without a law.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done :)
|
||
def empty[A]: Set[A] = Set.empty[A] | ||
|
||
def combineK[A](x: Set[A], y: Set[A]): Set[A] = x | y | ||
|
||
def foldLeft[A, B](fa: Set[A], b: B)(f: (B, A) => B): B = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same concern here about adding a law that this violates. Maybe a == b implies toList(a) == toList(b)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're going to need to spend some more time to find something. That one won't work, because that way e.g
Either.Left(123) =!= Either.Left(-30)
would imply List() =!= List()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it's the best solution but I worked around it, by only considering the positive case. I.e a == b
implies toList(a) == toList(b)
but not a != b
implies toList(a) != toList(b)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I meant (which is why I didn’t say (a == b) == (a.toList == b.toList))
59a760a
to
8745b55
Compare
This looks good to me. One question: do you know if this test would actually have caught Map/Set problems? I guess it must have since small maps/sets are just tuples and created in the order added. |
Yes I tested these on master and they failed for set/map. |
Although to be fair, I ran into some problems because it might not actually generate a situation where the tests fail every time because it's rare that they generate two different collections with the same values but different orderings. |
e32a461
to
37e36ea
Compare
realized that the Foldable test could be improved.
SortedMap
and SortedSet
instances
I couldn't think of a way to write the law so that will consistently fail on unordered data types either. Another option we have is to simply remove the |
SortedMap
and SortedSet
instancesSortedMap
and SortedSet
instances/Move Set
and Map
instances to Alleycats
thanks so much for pushing this through |
Should fix #1966