Skip to content

Commit baa0544

Browse files
author
Luka Jacobowitz
committed
Add control and move transformer instances to companion
1 parent 6cd9eb0 commit baa0544

File tree

8 files changed

+64
-76
lines changed

8 files changed

+64
-76
lines changed

core/src/main/scala/cats/ErrorControl.scala

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
package cats
22

3-
import cats.data.EitherT
3+
import cats.data._
44

55
trait ErrorControl[F[_], G[_], E] extends Serializable {
6-
val monadErrorF: MonadError[F, E]
7-
val monadG: Monad[G]
6+
def monadErrorF: MonadError[F, E]
7+
def monadG: Monad[G]
88

99
def controlError[A](fa: F[A])(f: E => G[A]): G[A]
1010

1111
def accept[A](ga: G[A]): F[A]
1212

13+
def control[A,B](fa: F[A])(f: Either[E, A] => G[B]): G[B] =
14+
monadG.flatMap(trial(fa))(f)
15+
1316
def trial[A](fa: F[A]): G[Either[E, A]] =
1417
intercept(monadErrorF.map(fa)(Right(_): Either[E, A]))(Left(_))
1518

@@ -35,4 +38,61 @@ object ErrorControl {
3538

3639
def apply[F[_], G[_], E](implicit ev: ErrorControl[F, G, E]): ErrorControl[F, G, E] = ev
3740

41+
42+
implicit def catsErrorControlForStateT[F[_], G[_], S, E]
43+
(implicit E: ErrorControl[F, G, E]): ErrorControl[StateT[F, S, ?], StateT[G, S, ?], E] =
44+
new ErrorControl[StateT[F, S, ?], StateT[G, S, ?], E] {
45+
implicit val F: MonadError[F, E] = E.monadErrorF
46+
implicit val G: Monad[G] = E.monadG
47+
48+
val monadErrorF: MonadError[StateT[F, S, ?], E] = IndexedStateT.catsDataMonadErrorForIndexedStateT
49+
val monadG: Monad[StateT[G, S, ?]] = IndexedStateT.catsDataMonadForIndexedStateT
50+
51+
def accept[A](ga: StateT[G, S, A]): StateT[F, S, A] = ga.mapK(new (G ~> F) {
52+
def apply[T](ga: G[T]): F[T] = E.accept(ga)
53+
})
54+
55+
def controlError[A](fa: StateT[F, S, A])(f: E => StateT[G, S, A]): StateT[G, S, A] =
56+
IndexedStateT(s => E.controlError(fa.run(s))(e => f(e).run(s)))
57+
58+
}
59+
60+
61+
implicit def catsErrorControlForKleisli[F[_], G[_], R, E]
62+
(implicit E: ErrorControl[F, G, E]): ErrorControl[Kleisli[F, R, ?], Kleisli[G, R, ?], E] =
63+
new ErrorControl[Kleisli[F, R, ?], Kleisli[G, R, ?], E] {
64+
implicit val F: MonadError[F, E] = E.monadErrorF
65+
implicit val G: Monad[G] = E.monadG
66+
67+
val monadErrorF: MonadError[Kleisli[F, R, ?], E] = Kleisli.catsDataMonadErrorForKleisli
68+
val monadG: Monad[Kleisli[G, R, ?]] = Kleisli.catsDataMonadForKleisli
69+
70+
def accept[A](ga: Kleisli[G, R, A]): Kleisli[F, R, A] = ga.mapK(new (G ~> F) {
71+
def apply[T](ga: G[T]): F[T] = E.accept(ga)
72+
})
73+
74+
def controlError[A](fa: Kleisli[F, R, A])(f: E => Kleisli[G, R, A]): Kleisli[G, R, A] =
75+
Kleisli(r => E.controlError(fa.run(r))(e => f(e).run(r)))
76+
77+
}
78+
79+
80+
implicit def catsErrorControlForWriterT[F[_], G[_], L: Monoid, E]
81+
(implicit M: ErrorControl[F, G, E]): ErrorControl[WriterT[F, L, ?], WriterT[G, L, ?], E] =
82+
new ErrorControl[WriterT[F, L, ?], WriterT[G, L, ?], E] {
83+
implicit val F: MonadError[F, E] = M.monadErrorF
84+
implicit val G: Monad[G] = M.monadG
85+
86+
val monadErrorF: MonadError[WriterT[F, L, ?], E] = WriterT.catsDataMonadErrorForWriterT
87+
val monadG: Monad[WriterT[G, L, ?]] = WriterT.catsDataMonadForWriterT
88+
89+
def accept[A](ga: WriterT[G, L, A]): WriterT[F, L, A] = ga.mapK(new (G ~> F) {
90+
def apply[T](ga: G[T]): F[T] = M.accept(ga)
91+
})
92+
93+
def controlError[A](fa: WriterT[F, L, A])(f: E => WriterT[G, L, A]): WriterT[G, L, A] =
94+
WriterT(M.controlError(fa.run)(e => f(e).run))
95+
96+
}
97+
3898
}

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

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -246,23 +246,6 @@ private[data] sealed abstract class IndexedStateTInstances extends IndexedStateT
246246
implicit def catsDataAlternativeForIndexedStateT[F[_], S](implicit FM: Monad[F],
247247
FA: Alternative[F]): Alternative[IndexedStateT[F, S, S, ?]] with Monad[IndexedStateT[F, S, S, ?]] =
248248
new IndexedStateTAlternative[F, S] { implicit def F = FM; implicit def G = FA }
249-
250-
implicit def catsErrorControlForStateT[F[_], G[_], S, E]
251-
(implicit E: ErrorControl[F, G, E], M: Monad[G]): ErrorControl[StateT[F, S, ?], StateT[G, S, ?], E] =
252-
new ErrorControl[StateT[F, S, ?], StateT[G, S, ?], E] {
253-
implicit val F: MonadError[F, E] = E.monadErrorF
254-
255-
val monadErrorF: MonadError[StateT[F, S, ?], E] = IndexedStateT.catsDataMonadErrorForIndexedStateT
256-
val monadG: Monad[StateT[G, S, ?]] = IndexedStateT.catsDataMonadForIndexedStateT(M)
257-
258-
def accept[A](ga: StateT[G, S, A]): StateT[F, S, A] = ga.mapK(new (G ~> F) {
259-
def apply[T](ga: G[T]): F[T] = E.accept(ga)
260-
})
261-
262-
def controlError[A](fa: StateT[F, S, A])(f: E => StateT[G, S, A]): StateT[G, S, A] =
263-
IndexedStateT(s => E.controlError(fa.run(s))(e => f(e).run(s)))
264-
265-
}
266249
}
267250

268251
private[data] sealed abstract class IndexedStateTInstances1 extends IndexedStateTInstances2 {

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

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -163,23 +163,6 @@ private[data] sealed abstract class KleisliInstances extends KleisliInstances0 {
163163
def F: Monad[F] = M
164164
}
165165

166-
implicit def catsErrorControlForKleisli[F[_], G[_], R, E]
167-
(implicit E: ErrorControl[F, G, E]): ErrorControl[Kleisli[F, R, ?], Kleisli[G, R, ?], E] =
168-
new ErrorControl[Kleisli[F, R, ?], Kleisli[G, R, ?], E] {
169-
implicit val F: MonadError[F, E] = E.monadErrorF
170-
implicit val G: Monad[G] = E.monadG
171-
172-
val monadErrorF: MonadError[Kleisli[F, R, ?], E] = Kleisli.catsDataMonadErrorForKleisli
173-
val monadG: Monad[Kleisli[G, R, ?]] = Kleisli.catsDataMonadForKleisli
174-
175-
def accept[A](ga: Kleisli[G, R, A]): Kleisli[F, R, A] = ga.mapK(new (G ~> F) {
176-
def apply[T](ga: G[T]): F[T] = E.accept(ga)
177-
})
178-
179-
def controlError[A](fa: Kleisli[F, R, A])(f: E => Kleisli[G, R, A]): Kleisli[G, R, A] =
180-
Kleisli(r => E.controlError(fa.run(r))(e => f(e).run(r)))
181-
182-
}
183166
}
184167

185168
private[data] sealed abstract class KleisliInstances0 extends KleisliInstances1 {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ private[data] sealed abstract class OptionTInstances extends OptionTInstances0 {
217217
implicit def catsDataMonadForOptionT[F[_]](implicit F0: Monad[F]): Monad[OptionT[F, ?]] =
218218
new OptionTMonad[F] { implicit val F = F0 }
219219

220-
implicit def catsEndeavorForOptionT[F[_]: Monad, E]: ErrorControl[OptionT[F, ?], F, Unit] =
220+
implicit def catsErrorControlForOptionT[F[_]: Monad, E]: ErrorControl[OptionT[F, ?], F, Unit] =
221221
new ErrorControl[OptionT[F, ?], F, Unit] {
222222
val monadErrorF: MonadError[OptionT[F, ?], Unit] = catsDataMonadErrorUnitForOptionT
223223
val monadG: Monad[F] = Monad[F]

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

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -107,24 +107,6 @@ private[data] sealed abstract class WriterTInstances extends WriterTInstances0 {
107107
implicit val L0: Monoid[L] = L
108108
}
109109

110-
implicit def catsErrorControlForWriterT[F[_], G[_], L: Monoid, E]
111-
(implicit M: ErrorControl[F, G, E]): ErrorControl[WriterT[F, L, ?], WriterT[G, L, ?], E] =
112-
new ErrorControl[WriterT[F, L, ?], WriterT[G, L, ?], E] {
113-
implicit val F: MonadError[F, E] = M.monadErrorF
114-
implicit val G: Monad[G] = M.monadG
115-
116-
val monadErrorF: MonadError[WriterT[F, L, ?], E] = WriterT.catsDataMonadErrorForWriterT
117-
val monadG: Monad[WriterT[G, L, ?]] = WriterT.catsDataMonadForWriterT
118-
119-
def accept[A](ga: WriterT[G, L, A]): WriterT[F, L, A] = ga.mapK(new (G ~> F) {
120-
def apply[T](ga: G[T]): F[T] = M.accept(ga)
121-
})
122-
123-
def controlError[A](fa: WriterT[F, L, A])(f: E => WriterT[G, L, A]): WriterT[G, L, A] =
124-
WriterT(M.controlError(fa.run)(e => f(e).run))
125-
126-
}
127-
128110
implicit def catsDataTraverseForWriterTId[L](implicit F: Traverse[Id]): Traverse[WriterT[Id, L, ?]] =
129111
catsDataTraverseForWriterT[Id, L](F)
130112
}

tests/src/test/scala/cats/tests/IndexedStateTSuite.scala

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,6 @@ class IndexedStateTSuite extends CatsSuite {
404404
checkAll("StateT[Option, Int, Int]", MonadErrorTests[StateT[Option, Int, ?], Unit].monadError[Int, Int, Int])
405405
checkAll("MonadError[StateT[Option, Int, ?], Unit]", SerializableTests.serializable(MonadError[StateT[Option, Int , ?], Unit]))
406406

407-
//TODO: Why can't type inference figure this out?
408-
implicit val x: ErrorControl[StateT[Option, Int, ?], StateT[Id, Int, ?], Unit] =
409-
IndexedStateT.catsErrorControlForStateT[Option, Id, Int, Unit]
410-
411407
checkAll("StateT[EitherT[Option, String, ?], Int, ?]",
412408
ErrorControlTests[StateT[EitherT[Option, String, ?], Int, ?], StateT[Option, Int, ?], String].errorControl[Int])
413409
checkAll("ErrorControl[StateT[EitherT[Option, String, ?], Int, ?], StateT[Option, Int, ?], String]",

tests/src/test/scala/cats/tests/KleisliSuite.scala

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,6 @@ class KleisliSuite extends CatsSuite {
4747
checkAll("Kleisli[Id, Int, ?]", CommutativeMonadTests[Kleisli[Id, Int, ?]].commutativeMonad[Int, Int, Int])
4848
checkAll("CommutativeMonad[Kleisli[Id, Int, ?]]", SerializableTests.serializable(CommutativeMonad[Kleisli[Id, Int, ?]]))
4949

50-
//TODO: Why can't type inference figure this out?
51-
implicit val x: ErrorControl[Kleisli[Option, Int, ?], Kleisli[Id, Int, ?], Unit] =
52-
Kleisli.catsErrorControlForKleisli[Option, Id, Int, Unit]
53-
54-
checkAll("Kleisli[Option, Int, ?]", ErrorControlTests[Kleisli[Option, Int, ?], Kleisli[Id, Int, ?], Unit].errorControl[Int])
55-
checkAll("ErrorControl[Kleisli[Option, Int, ?], Kleisli[Id, Int, ?], Unit]",
56-
SerializableTests.serializable(ErrorControl[Kleisli[Option, Int, ?], Kleisli[Id, Int, ?], Unit]))
57-
5850
checkAll("Kleisli[EitherT[Option, String, ?], Int, ?]",
5951
ErrorControlTests[Kleisli[EitherT[Option, String, ?], Int, ?], Kleisli[Option, Int, ?], String].errorControl[Int])
6052
checkAll("ErrorControl[Kleisli[EitherT[Option, String, ?], Int, ?], Kleisli[Option, Int, ?], String]",

tests/src/test/scala/cats/tests/WriterTSuite.scala

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@ class WriterTSuite extends CatsSuite {
2424
checkAll("WriterT[Show, Int, Int]", ContravariantTests[WriterT[Show, Int, ?]].contravariant[Int, Int, Int])
2525
checkAll("Contravariant[WriterT[Show, Int, Int]]", SerializableTests.serializable(Contravariant[WriterT[Show, Int, ?]]))
2626

27-
//TODO: Why can't type inference figure this out?
28-
implicit val x: ErrorControl[WriterT[Option, Int, ?], WriterT[Id, Int, ?], Unit] =
29-
WriterT.catsErrorControlForWriterT[Option, Id, Int, Unit]
30-
31-
checkAll("WriterT[Option, Int, ?]", ErrorControlTests[WriterT[Option, Int, ?], WriterT[Id, Int, ?], Unit].errorControl[Int])
32-
checkAll("ErrorControl[WriterT[Option, Int, ?], WriterT[Id, Int, ?], Unit]",
33-
SerializableTests.serializable(ErrorControl[WriterT[Option, Int, ?], WriterT[Id, Int, ?], Unit]))
34-
3527
checkAll("WriterT[EitherT[Option, String, ?], Int, ?]",
3628
ErrorControlTests[WriterT[EitherT[Option, String, ?], Int, ?], WriterT[Option, Int, ?], String].errorControl[Int])
3729
checkAll("ErrorControl[WriterT[EitherT[Option, String, ?], Int, ?], WriterT[Option, Int, ?], String]",

0 commit comments

Comments
 (0)