3 ms·
I am also really annoyed by how Set and Map's map methods work in Scala (and have argued about it here: https://contributors.scala-lang.org/t/set-map-deduping-a
by joshlemer 7y ago
I am also really annoyed by how Set and Map's map methods work in Scala (and have argued about it here: https://contributors.scala-lang.org/t/set-map-deduping-and-possibly-unsafe-behavior/3436 https://contributors.scala-lang.org/t/set-map-deduping-and-p...), I actually don't think that for all the shortcomings of the Set map method, it actually violates any of the Functor laws:
1) For all sets s, s.map(identity) == s ==> true
2) For all sets s, functions f and g,
s.map(x => f(g(x)) == s.map(g).map(f) ==> true
On the other hand, Map's map method is much more horrible, and does violate the 2nd functor law where f == g == _.swap :
Map(1 -> 2, 2 -> 2).map(_.swap).map(_.swap) ==> Map(2 -> 2)
Map(1 -> 2, 2 -> 2).map(_.swap.swap) ==> Map(1 -> 2, 2 -> 2)
Further, it behaves differently depending on if it is known to be a Map at compile-time, or if it is only known to be an Iterable[(K, V)], due to overloading:
Map(1 -> 2, 2 -> 2).map(_.swap) ==> Map(2 -> 2)
(Map(1 -> 2, 2 -> 2): Iterable[(Int, Int)]).map(_.swap) ==> List(2 -> 1, 2 -> 2)
- dmit 7y agoAh, you're correct of course, as is TJSomething. While Cats and Scalaz don't provide a Functor instance for Set (and neither does Haskell for Data.Set), it's not for the reason I mentioned.