Skip to content

Commit 44ff278

Browse files
authored
Merge pull request #4735 from danicheg/empty-map-instance
Add the `Empty[Map[A, B]]` instance in alleycats
2 parents 324d528 + d5a7e2f commit 44ff278

2 files changed

Lines changed: 33 additions & 10 deletions

File tree

alleycats-core/src/main/scala/alleycats/Empty.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ package alleycats
2424
import cats.{Eq, Monoid}
2525
import cats.syntax.eq.*
2626

27+
import scala.collection.immutable.SortedMap
28+
2729
trait Empty[A] extends Serializable {
2830
def empty: A
2931

@@ -78,8 +80,15 @@ object Empty extends EmptyInstances0 {
7880
}
7981

8082
private[alleycats] trait EmptyInstances0 extends compat.IterableEmptyInstance with EmptyInstances1 {
83+
8184
private[this] val emptyOptionSingleton: Empty[Option[Nothing]] = Empty(None)
8285
implicit def alleycatsEmptyForOption[A]: Empty[Option[A]] = emptyOptionSingleton.asInstanceOf[Empty[Option[A]]]
86+
87+
private[this] val emptyMapSingleton: Empty[Map[Nothing, Nothing]] = Empty(Map.empty)
88+
implicit def alleycatsEmptyForMap[A, B]: Empty[Map[A, B]] = emptyMapSingleton.asInstanceOf[Empty[Map[A, B]]]
89+
90+
implicit def alleycatsEmptyForSortedMap[A: Ordering, B]: Empty[SortedMap[A, B]] =
91+
Empty(SortedMap.empty[A, B])
8392
}
8493

8594
private[alleycats] trait EmptyInstances1 extends EmptyInstances2 {

alleycats-core/src/test/scala/alleycats/SyntaxSuite.scala

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ package alleycats
2424
import cats.{Eq, Foldable}
2525
import alleycats.syntax.all.{catsSyntaxExtract, EmptyOps, ExtraFoldableOps}
2626

27+
import scala.collection.immutable.SortedMap
28+
2729
/**
2830
* Test that our syntax implicits are working.
2931
*
@@ -47,33 +49,45 @@ object SyntaxSuite {
4749
// pretend we have a value of type A
4850
def mock[A]: A = ???
4951

50-
def testEmpty[A: Empty]: Unit = {
52+
def testEmpty[A: Empty](): Unit = {
5153
val x = mock[A]
5254
implicit val y: Eq[A] = mock[Eq[A]]
53-
val a0: Boolean = x.isEmpty
54-
val a1: Boolean = x.nonEmpty
55+
val _ = x.isEmpty | x.nonEmpty
5556
}
5657

57-
def testOptionEmpty: Unit = {
58+
def testOptionEmpty(): Unit = {
5859
case class A[T](x: T)
5960
case class B()
6061

61-
import alleycats.std.option.*
6262
implicit def emptyA[T: Empty]: Empty[A[T]] = new Empty[A[T]] {
6363
def empty: A[T] = A(Empty[T].empty)
6464
}
6565

66-
Empty[A[Option[B]]].empty
66+
val _ = Empty[A[Option[B]]].empty
67+
}
68+
69+
def testMapEmpty(): Any = {
70+
case class Foo[A](foo: A)
71+
72+
val _ = Empty[Map[Foo[Int], Foo[String]]].empty
73+
}
74+
75+
def testSortedMapEmpty(): Any = {
76+
case class Foo[A](foo: A)
77+
78+
implicit def fooOrd[A: Ordering]: Ordering[Foo[A]] = Ordering.by(_.foo)
79+
80+
val _ = Empty[SortedMap[Foo[Int], Foo[String]]].empty
6781
}
6882

69-
def testFoldable[F[_]: Foldable, A]: Unit = {
83+
def testFoldable[F[_]: Foldable, A](): Unit = {
7084
val x = mock[F[A]]
7185
val y = mock[A => Unit]
72-
x.foreach(y)
86+
val _ = x.foreach(y)
7387
}
7488

75-
def testExtract[F[_]: Extract, A]: Unit = {
89+
def testExtract[F[_]: Extract, A](): Unit = {
7690
val x = mock[F[A]]
77-
val y = x.extract
91+
val _ = x.extract
7892
}
7993
}

0 commit comments

Comments
 (0)