Skip to content

Instantly share code, notes, and snippets.

@tpolecat
Last active August 29, 2020 08:00
Show Gist options
  • Save tpolecat/7401433 to your computer and use it in GitHub Desktop.
Save tpolecat/7401433 to your computer and use it in GitHub Desktop.
set is not a functor mkay
scala> case class Bad(a: Int) { override def equals(a:Any) = true }
scala> val f = (n:Int) => Bad(n)
scala> val g = (b:Bad) => b.a
...
scala> Set(1,2,3).map(f andThen g)
res2: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> Set(1,2,3).map(f).map(g)
res3: scala.collection.immutable.Set[Int] = Set(1)
@EncodePanda
Copy link

this implementation actually breaks 'equals' contract defined in Java Specification Language, but I can think of example that does not break it but breaks Functor laws for set

@EncodePanda
Copy link

scala> case class Weird(n: Int) {
     | override def equals(obj: Any):Boolean = if(n == 1 && obj.asInstanceOf[Weird].n == 1) true else false
     | }
defined class Weird

scala> val set = (1 to 10).toSet
set: scala.collection.immutable.Set[Int] = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4)

scala> val f: Int => Weird = a => Weird(a % 2)
f: Int => Weird = <function1>

scala> val g: Weird => Weird = w => if(w.n == 1) Weird(2) else w
g: Weird => Weird = <function1>

scala> set.map(f andThen g)
res3: scala.collection.immutable.Set[Weird] = Set(Weird(0), Weird(0), Weird(0), Weird(0), Weird(0), Weird(2), Weird(2), Weird(2), Weird(2), Weird(2))

scala> set.map(f).map(g)
res4: scala.collection.immutable.Set[Weird] = Set(Weird(0), Weird(0), Weird(0), Weird(0), Weird(0), Weird(2))

@tpolecat
Copy link
Author

Functor says for all A.

@EncodePanda
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment