-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #34 from TinkoffCreditSystems/daemons
daemon extensions, instances and syntax
- Loading branch information
Showing
6 changed files
with
151 additions
and
8 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,67 @@ | ||
package tofu.concurrent | ||
|
||
import cats.{Applicative, Eval, Traverse} | ||
import cats.effect.ExitCase | ||
import tofu.control.ApplicativeZip | ||
import tofu.syntax.monadic._ | ||
|
||
sealed trait Exit[+E, +A] { | ||
def exitCase: ExitCase[E] | ||
} | ||
|
||
object Exit { | ||
case object Canceled extends Exit[Nothing, Nothing] { | ||
|
||
sealed trait Incomplete[+E] extends Exit[E, Nothing] | ||
|
||
case object Canceled extends Incomplete[Nothing] { | ||
def exitCase = ExitCase.Canceled | ||
} | ||
final case class Error[+E](e: E) extends Exit[E, Nothing] { | ||
final case class Error[+E](e: E) extends Incomplete[E] { | ||
def exitCase = ExitCase.Error(e) | ||
} | ||
final case class Completed[+A](a: A) extends Exit[Nothing, A] { | ||
override def exitCase = ExitCase.Completed | ||
} | ||
|
||
|
||
private[this] object exitInstanceAny extends Traverse[Exit[Any, *]] with ApplicativeZip[Exit[Any, *]] { | ||
def traverse[G[_], A, B](fa: Exit[Any, A])(f: A => G[B])(implicit G: Applicative[G]): G[Exit[Any, B]] = | ||
fa match { | ||
case Canceled => G.pure(Canceled) | ||
case Error(e) => G.pure(Error(e)) | ||
case Completed(a) => f(a).map(Completed(_)) | ||
} | ||
def foldLeft[A, B](fa: Exit[Any, A], b: B)(f: (B, A) => B): B = | ||
fa match { | ||
case Canceled | Error(_) => b | ||
case Completed(a) => f(b, a) | ||
} | ||
def foldRight[A, B](fa: Exit[Any, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = | ||
fa match { | ||
case Canceled | Error(_) => lb | ||
case Completed(a) => f(a, lb) | ||
} | ||
override def map[A, B](fa: Exit[Any, A])(f: A => B): Exit[Any, B] = | ||
fa match { | ||
case Canceled => Canceled | ||
case e: Error[Any] => e | ||
case Completed(a) => Completed(f(a)) | ||
} | ||
|
||
def zipWith[A, B, C](fa: Exit[Any, A], fb: Exit[Any, B])(f: (A, B) => C): Exit[Any, C] = | ||
fa match { | ||
case Canceled => Canceled | ||
case err: Error[Any] => err | ||
case Completed(a) => | ||
fb match { | ||
case Canceled => Canceled | ||
case err: Error[Any] => err | ||
case Completed(b) => Completed(f(a, b)) | ||
} | ||
} | ||
def pure[A](x: A): Exit[Any, A] = Completed(x) | ||
} | ||
|
||
implicit def exitInstance[E]: Traverse[Exit[E, *]] with Applicative[Exit[E, *]] = | ||
exitInstanceAny.asInstanceOf[Traverse[Exit[E, *]] with Applicative[Exit[E, *]]] | ||
} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package tofu | ||
package concurrent | ||
import tofu.lift.Lift | ||
import tofu.syntax.lift._ | ||
|
||
object SyntaxCheck { | ||
def liftDaemon[F[_], G[_], E, A](daemon: Daemon[F, E, A])(implicit lift: Lift[F, G]): Daemon[G, E, A] = | ||
daemon.lift2[G] | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package tofu.control | ||
import cats.{Applicative, Apply} | ||
|
||
/** mix-in for Apply instances via `map2`*/ | ||
trait ApplyZip[F[_]] extends Apply[F] { | ||
def zipWith[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] | ||
|
||
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] = zipWith(ff, fa)(_ apply _) | ||
} | ||
|
||
/** mix-in for Applicative instances via `map2`*/ | ||
trait ApplicativeZip[F[_]] extends ApplyZip[F] with Applicative[F] { | ||
override def map[A, B](fa: F[A])(f: A => B): F[B] = zipWith(fa, unit)((a, _) => f(a)) | ||
} |
This file contains 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