Skip to content

Commit 3058538

Browse files
committed
Merge branch 'master' of https://github.com/non/cats into monoidal-functors
2 parents ecd307e + 48286f2 commit 3058538

45 files changed

Lines changed: 1040 additions & 219 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ lazy val freeJVM = free.jvm
153153
lazy val freeJS = free.js
154154

155155
lazy val state = crossProject.crossType(CrossType.Pure)
156-
.dependsOn(macros, core, free, tests % "test-internal -> test")
156+
.dependsOn(macros, core, free % "compile-internal;test-internal -> test", tests % "test-internal -> test")
157157
.settings(moduleName := "cats-state")
158158
.settings(catsSettings:_*)
159159
.jsSettings(commonJsSettings:_*)

core/src/main/scala/cats/arrow/NaturalTransformation.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@ trait NaturalTransformation[F[_], G[_]] extends Serializable { self =>
1313

1414
def andThen[H[_]](f: NaturalTransformation[G, H]): NaturalTransformation[F, H] =
1515
f.compose(self)
16+
17+
def or[H[_]](h: H ~> G): Coproduct[F, H, ?] ~> G =
18+
new (Coproduct[F, H, ?] ~> G) {
19+
def apply[A](fa: Coproduct[F, H, A]): G[A] = fa.run match {
20+
case Xor.Left(ff) => self(ff)
21+
case Xor.Right(gg) => h(gg)
22+
}
23+
}
1624
}
1725

1826
object NaturalTransformation {
1927
def id[F[_]]: NaturalTransformation[F, F] =
2028
new NaturalTransformation[F, F] {
2129
def apply[A](fa: F[A]): F[A] = fa
2230
}
23-
24-
def or[F[_], G[_], H[_]](f: F ~> H, g: G ~> H): Coproduct[F, G, ?] ~> H =
25-
new (Coproduct[F, G, ?] ~> H) {
26-
def apply[A](fa: Coproduct[F, G, A]): H[A] = fa.run match {
27-
case Xor.Left(ff) => f(ff)
28-
case Xor.Right(gg) => g(gg)
29-
}
30-
}
3131
}

core/src/main/scala/cats/data/Const.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 {
7272
}
7373

7474
private[data] sealed abstract class ConstInstances0 extends ConstInstances1 {
75+
76+
implicit def constSemigroup[A: Semigroup, B]: Semigroup[Const[A, B]] = new Semigroup[Const[A, B]] {
77+
def combine(x: Const[A, B], y: Const[A, B]): Const[A, B] = x combine y
78+
}
79+
7580
implicit def constPartialOrder[A: PartialOrder, B]: PartialOrder[Const[A, B]] = new PartialOrder[Const[A, B]]{
7681
def partialCompare(x: Const[A, B], y: Const[A, B]): Double =
7782
x partialCompare y

core/src/main/scala/cats/data/OptionT.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,18 @@ private[data] sealed trait OptionTInstances1 {
137137
}
138138

139139
private[data] sealed trait OptionTInstances extends OptionTInstances1 {
140-
implicit def optionTMonadCombine[F[_]](implicit F: Monad[F]): MonadCombine[OptionT[F, ?]] =
141-
new MonadCombine[OptionT[F, ?]] {
140+
141+
implicit def optionTMonad[F[_]](implicit F: Monad[F]): Monad[OptionT[F, ?]] =
142+
new Monad[OptionT[F, ?]] {
142143
def pure[A](a: A): OptionT[F, A] = OptionT.pure(a)
143144

144145
def flatMap[A, B](fa: OptionT[F, A])(f: A => OptionT[F, B]): OptionT[F, B] =
145146
fa.flatMap(f)
146147

147148
override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] =
148149
fa.map(f)
149-
150-
override def empty[A]: OptionT[F,A] = OptionT(F.pure(None))
151-
override def combine[A](x: OptionT[F,A], y: OptionT[F,A]): OptionT[F,A] = x orElse y
152150
}
151+
153152
implicit def optionTEq[F[_], A](implicit FA: Eq[F[Option[A]]]): Eq[OptionT[F, A]] =
154153
FA.on(_.value)
155154

core/src/main/scala/cats/data/StreamingT.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,12 @@ sealed abstract class StreamingT[F[_], A] extends Product with Serializable { lh
273273
* This method will not force evaluation of any lazy part of a
274274
* stream. As a result, you will see at most one element (the first
275275
* one).
276-
*
277-
* Use .toString(n) to see the first n elements of the stream.
278276
*/
279-
override def toString: String =
280-
"StreamingT(...)"
277+
override def toString: String = this match {
278+
case Cons(a, _) => s"StreamingT($a, ...)"
279+
case Wait(_) => "StreamingT(...)"
280+
case Empty() => "StreamingT()"
281+
}
281282
}
282283

283284
object StreamingT extends StreamingTInstances {

core/src/main/scala/cats/data/Validated.scala

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,21 @@ sealed abstract class Validated[+E, +A] extends Product with Serializable {
178178
case Valid(a) => f(a)
179179
case i @ Invalid(_) => i
180180
}
181+
182+
/**
183+
* Combine this `Validated` with another `Validated`, using the `Semigroup`
184+
* instances of the underlying `E` and `A` instances. The resultant `Validated`
185+
* will be `Valid`, if, and only if, both this `Validated` instance and the
186+
* supplied `Validated` instance are also `Valid`.
187+
*/
188+
def combine[EE >: E, AA >: A](that: Validated[EE, AA])(implicit EE: Semigroup[EE], AA: Semigroup[AA]): Validated[EE, AA] =
189+
(this, that) match {
190+
case (Valid(a), Valid(b)) => Valid(AA.combine(a, b))
191+
case (Invalid(a), Invalid(b)) => Invalid(EE.combine(a, b))
192+
case (Invalid(_), _) => this
193+
case _ => that
194+
}
195+
181196
}
182197

183198
object Validated extends ValidatedInstances with ValidatedFunctions{
@@ -187,6 +202,12 @@ object Validated extends ValidatedInstances with ValidatedFunctions{
187202

188203

189204
private[data] sealed abstract class ValidatedInstances extends ValidatedInstances1 {
205+
206+
implicit def validatedMonoid[A, B](implicit A: Semigroup[A], B: Monoid[B]): Monoid[Validated[A, B]] = new Monoid[Validated[A, B]] {
207+
def empty: Validated[A, B] = Valid(B.empty)
208+
def combine(x: Validated[A, B], y: Validated[A, B]): Validated[A, B] = x combine y
209+
}
210+
190211
implicit def validatedOrder[A: Order, B: Order]: Order[Validated[A,B]] = new Order[Validated[A,B]] {
191212
def compare(x: Validated[A,B], y: Validated[A,B]): Int = x compare y
192213
override def partialCompare(x: Validated[A,B], y: Validated[A,B]): Double = x partialCompare y
@@ -228,6 +249,12 @@ private[data] sealed abstract class ValidatedInstances extends ValidatedInstance
228249
}
229250

230251
private[data] sealed abstract class ValidatedInstances1 extends ValidatedInstances2 {
252+
253+
implicit def validatedSemigroup[A, B](implicit A: Semigroup[A], B: Semigroup[B]): Semigroup[Validated[A, B]] =
254+
new Semigroup[Validated[A, B]] {
255+
def combine(x: Validated[A, B], y: Validated[A, B]): Validated[A, B] = x combine y
256+
}
257+
231258
implicit def validatedPartialOrder[A: PartialOrder, B: PartialOrder]: PartialOrder[Validated[A,B]] =
232259
new PartialOrder[Validated[A,B]] {
233260
def partialCompare(x: Validated[A,B], y: Validated[A,B]): Double = x partialCompare y
@@ -295,4 +322,3 @@ trait ValidatedFunctions {
295322
*/
296323
def fromOption[A, B](o: Option[B], ifNone: => A): Validated[A,B] = o.fold(invalid[A, B](ifNone))(valid)
297324
}
298-

core/src/main/scala/cats/data/WriterT.scala

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ private[data] sealed abstract class WriterTInstances extends WriterTInstances0 {
6565
}
6666

6767
private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 {
68-
implicit def writerTMonad[F[_], L](implicit F: Monad[F], L: Monoid[L]): Monad[WriterT[F, L, ?]] =
69-
new WriterTMonad[F, L] {
70-
implicit val F0: Monad[F] = F
68+
implicit def writerTMonadCombine[F[_], L](implicit F: MonadCombine[F], L: Monoid[L]): MonadCombine[WriterT[F, L, ?]] =
69+
new WriterTMonadCombine[F, L] {
70+
implicit val F0: MonadCombine[F] = F
7171
implicit val L0: Monoid[L] = L
7272
}
7373

@@ -82,29 +82,63 @@ private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1
8282
}
8383

8484
private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 {
85+
implicit def writerTMonadFilter[F[_], L](implicit F: MonadFilter[F], L: Monoid[L]): MonadFilter[WriterT[F, L, ?]] =
86+
new WriterTMonadFilter[F, L] {
87+
implicit val F0: MonadFilter[F] = F
88+
implicit val L0: Monoid[L] = L
89+
}
90+
}
91+
private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 {
92+
implicit def writerTMonad[F[_], L](implicit F: Monad[F], L: Monoid[L]): Monad[WriterT[F, L, ?]] =
93+
new WriterTMonad[F, L] {
94+
implicit val F0: Monad[F] = F
95+
implicit val L0: Monoid[L] = L
96+
}
97+
}
98+
99+
private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 {
100+
implicit def writerTAlternative[F[_], L](implicit F: Alternative[F], L: Monoid[L]): Alternative[WriterT[F, L, ?]] =
101+
new WriterTAlternative[F, L] {
102+
implicit val F0: Alternative[F] = F
103+
implicit val L0: Monoid[L] = L
104+
}
105+
}
106+
107+
private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 {
85108
implicit def writerTApplicative[F[_], L](implicit F: Applicative[F], L: Monoid[L]): Applicative[WriterT[F, L, ?]] =
86109
new WriterTApplicative[F, L] {
87110
implicit val F0: Applicative[F] = F
88111
implicit val L0: Monoid[L] = L
89112
}
113+
114+
implicit def writerTMonoidK[F[_], L](implicit F: MonoidK[F]): MonoidK[WriterT[F, L, ?]] =
115+
new WriterTMonoidK[F, L] {
116+
implicit val F0: MonoidK[F] = F
117+
}
90118
}
91-
private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 {
119+
120+
private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 {
92121
implicit def writerTFlatMap[F[_], L](implicit F: FlatMap[F], L: Semigroup[L]): FlatMap[WriterT[F, L, ?]] =
93122
new WriterTFlatMap[F, L] {
94123
implicit val F0: FlatMap[F] = F
95124
implicit val L0: Semigroup[L] = L
96125
}
126+
127+
implicit def writerTSemigroupK[F[_], L](implicit F: SemigroupK[F]): SemigroupK[WriterT[F, L, ?]] =
128+
new WriterTSemigroupK[F, L] {
129+
implicit val F0: SemigroupK[F] = F
130+
}
97131
}
98132

99-
private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 {
133+
private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 {
100134
implicit def writerTApply[F[_], L](implicit F: Apply[F], L: Semigroup[L]): Apply[WriterT[F, L, ?]] =
101135
new WriterTApply[F, L] {
102136
implicit val F0: Apply[F] = F
103137
implicit val L0: Semigroup[L] = L
104138
}
105139
}
106140

107-
private[data] sealed abstract class WriterTInstances4 {
141+
private[data] sealed abstract class WriterTInstances7 {
108142
implicit def writerTFunctor[F[_], L](implicit F: Functor[F]): Functor[WriterT[F, L, ?]] = new WriterTFunctor[F, L] {
109143
implicit val F0: Functor[F] = F
110144
}
@@ -151,6 +185,33 @@ private[data] sealed trait WriterTMonad[F[_], L] extends WriterTApplicative[F, L
151185
fa.flatMap(f)
152186
}
153187

188+
private[data] sealed trait WriterTSemigroupK[F[_], L] extends SemigroupK[WriterT[F, L, ?]] {
189+
implicit def F0: SemigroupK[F]
190+
191+
def combine[A](x: WriterT[F, L, A], y: WriterT[F, L, A]): WriterT[F, L, A] =
192+
WriterT(F0.combine(x.run, y.run))
193+
}
194+
195+
private[data] sealed trait WriterTMonoidK[F[_], L] extends MonoidK[WriterT[F, L, ?]] with WriterTSemigroupK[F, L] {
196+
override implicit def F0: MonoidK[F]
197+
198+
def empty[A]: WriterT[F, L, A] = WriterT(F0.empty)
199+
}
200+
201+
private[data] sealed trait WriterTAlternative[F[_], L] extends Alternative[WriterT[F, L, ?]] with WriterTMonoidK[F, L] with WriterTApplicative[F, L] {
202+
override implicit def F0: Alternative[F]
203+
}
204+
205+
private[data] sealed trait WriterTMonadFilter[F[_], L] extends MonadFilter[WriterT[F, L, ?]] with WriterTMonad[F, L] {
206+
override implicit def F0: MonadFilter[F]
207+
208+
def empty[A]: WriterT[F, L, A] = WriterT(F0.empty)
209+
}
210+
211+
private[data] sealed trait WriterTMonadCombine[F[_], L] extends MonadCombine[WriterT[F, L, ?]] with WriterTMonad[F, L] with WriterTAlternative[F, L] {
212+
override implicit def F0: MonadCombine[F]
213+
}
214+
154215
trait WriterTFunctions {
155216
def putT[F[_], L, V](vf: F[V])(l: L)(implicit functorF: Functor[F]): WriterT[F, L, V] =
156217
WriterT(functorF.map(vf)(v => (l, v)))

core/src/main/scala/cats/data/Xor.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ private[data] sealed abstract class XorInstances extends XorInstances1 {
194194
}
195195

196196
private[data] sealed abstract class XorInstances1 extends XorInstances2 {
197+
198+
implicit def xorSemigroup[A, B](implicit A: Semigroup[A], B: Semigroup[B]): Semigroup[A Xor B] =
199+
new Semigroup[A Xor B] {
200+
def combine(x: A Xor B, y: A Xor B): A Xor B = x combine y
201+
}
202+
197203
implicit def xorPartialOrder[A: PartialOrder, B: PartialOrder]: PartialOrder[A Xor B] = new PartialOrder[A Xor B] {
198204
def partialCompare(x: A Xor B, y: A Xor B): Double = x partialCompare y
199205
override def eqv(x: A Xor B, y: A Xor B): Boolean = x === y

core/src/main/scala/cats/data/XorT.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ final case class XorT[F[_], A, B](value: F[A Xor B]) {
2222

2323
def getOrElse[BB >: B](default: => BB)(implicit F: Functor[F]): F[BB] = F.map(value)(_.getOrElse(default))
2424

25+
def getOrElseF[BB >: B](default: => F[BB])(implicit F: Monad[F]): F[BB] = {
26+
F.flatMap(value) {
27+
case Xor.Left(_) => default
28+
case Xor.Right(b) => F.pure(b)
29+
}
30+
}
31+
32+
def orElse[AA >: A, BB >: B](default: => XorT[F, AA, BB])(implicit F: Monad[F]): XorT[F, AA, BB] = {
33+
XorT(F.flatMap(value) { xor =>
34+
xor match {
35+
case Xor.Left(_) => default.value
36+
case _ => F.pure(xor)
37+
}
38+
})
39+
}
40+
2541
def recover(pf: PartialFunction[A, B])(implicit F: Functor[F]): XorT[F, A, B] =
2642
XorT(F.map(value)(_.recover(pf)))
2743

@@ -277,10 +293,12 @@ private[data] trait XorTMonadFilter[F[_], L] extends MonadFilter[XorT[F, L, ?]]
277293
def empty[A]: XorT[F, L, A] = XorT(F.pure(Xor.left(L.empty)))
278294
}
279295

296+
/* TODO violates right absorbtion, right distributivity, and left distributivity -- re-enable when MonadCombine laws are split in to weak/strong
280297
private[data] trait XorTMonadCombine[F[_], L] extends MonadCombine[XorT[F, L, ?]] with XorTMonadFilter[F, L] with XorTSemigroupK[F, L] {
281298
implicit val F: Monad[F]
282299
implicit val L: Monoid[L]
283300
}
301+
*/
284302

285303
private[data] sealed trait XorTFoldable[F[_], L] extends Foldable[XorT[F, L, ?]] {
286304
implicit def F0: Foldable[F]

core/src/main/scala/cats/std/function.scala

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import cats.arrow.{Arrow, Choice}
66
import cats.data.Xor
77
import cats.functor.Contravariant
88

9-
trait Function0Instances {
9+
private[std] sealed trait Function0Instances {
1010
implicit val function0Instance: Bimonad[Function0] =
1111
new Bimonad[Function0] {
1212
def extract[A](x: () => A): A = x()
@@ -26,7 +26,7 @@ trait Function0Instances {
2626
}
2727
}
2828

29-
trait Function1Instances {
29+
private[std] sealed trait Function1Instances extends Function1Instances0 {
3030
implicit def function1Contravariant[R]: Contravariant[? => R] =
3131
new Contravariant[? => R] {
3232
def contramap[T1, T0](fa: T1 => R)(f: T0 => T1): T0 => R =
@@ -71,13 +71,41 @@ trait Function1Instances {
7171
def compose[A, B, C](f: B => C, g: A => B): A => C = f.compose(g)
7272
}
7373

74-
implicit def function1Monoid[A,B](implicit B: Monoid[B]): Monoid[A => B] =
75-
new Monoid[A => B] {
76-
def empty: A => B = _ => B.empty
77-
def combine(x: A => B, y: A => B): A => B = { a =>
78-
B.combine(x(a), y(a))
79-
}
80-
}
74+
implicit def function1Monoid[A,B](implicit M: Monoid[B]): Monoid[A => B] =
75+
new Function1Monoid[A, B] { def B: Monoid[B] = M }
76+
77+
implicit val function1MonoidK: MonoidK[Lambda[A => A => A]] =
78+
new Function1MonoidK {}
79+
}
80+
81+
private[std] sealed trait Function1Instances0 {
82+
implicit def function1Semigroup[A,B](implicit S: Semigroup[B]): Semigroup[A => B] =
83+
new Function1Semigroup[A, B] { def B: Semigroup[B] = S }
84+
85+
implicit val function1SemigroupK: SemigroupK[Lambda[A => A => A]] =
86+
new Function1SemigroupK {}
87+
}
88+
89+
private[std] sealed trait Function1Semigroup[A, B] extends Semigroup[A => B] {
90+
implicit def B: Semigroup[B]
91+
92+
override def combine(x: A => B, y: A => B): A => B = { a =>
93+
B.combine(x(a), y(a))
94+
}
95+
}
96+
97+
private[std] sealed trait Function1Monoid[A, B] extends Monoid[A => B] with Function1Semigroup[A, B] {
98+
implicit def B: Monoid[B]
99+
100+
override def empty: A => B = _ => B.empty
101+
}
102+
103+
private[std] sealed trait Function1SemigroupK extends SemigroupK[Lambda[A => A => A]] {
104+
override def combine[A](x: A => A, y: A => A): A => A = x compose y
105+
}
106+
107+
private[std] sealed trait Function1MonoidK extends MonoidK[Lambda[A => A => A]] with Function1SemigroupK {
108+
override def empty[A]: A => A = identity[A]
81109
}
82110

83111
trait FunctionInstances

0 commit comments

Comments
 (0)