Created
February 5, 2022 04:37
-
-
Save rossabaker/2f50e77cecc6afd096dd7895f763b5f6 to your computer and use it in GitHub Desktop.
Set is not a functor
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
scala> import org.typelevel.ci._ | |
import org.typelevel.ci._ | |
scala> val f: String => CIString = CIString.apply | |
val f: String => org.typelevel.ci.CIString = $Lambda$1025/2055291664@4bbf38b8 | |
scala> val g: CIString => String = _.toString | |
val g: org.typelevel.ci.CIString => String = $Lambda$1027/1152113439@62108cd3 | |
scala> val rosses = Set("Ross", "ROSS", "ross") // three too many if you ask me | |
val rosses: scala.collection.immutable.Set[String] = Set(Ross, ROSS, ross) | |
scala> rosses.map(f).map(g) | |
val res0: scala.collection.immutable.Set[String] = Set(Ross) | |
scala> rosses.map(f andThen g) | |
val res1: scala.collection.immutable.Set[String] = Set(Ross, ROSS, ross) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't know about "tricky".
CIString
satisfies the contract of.equals
. There's no substitution law.cats.Eq
doesn't have one either. Haskell'sEq
recently added it as an "expectation", but officially has no laws. We should strongly prefer that property, but it's neither illegal nor unusual to break it. A couple more examples:(s: Set[A] => s.toList)
(ordering is undefined)(d: Double) => 1.0 / d
(try it with0.0
and-0.0
)A set whose equivalence relation guarantees substitution is a functor, but Scala's
Set
doesn't, so it's not.