Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factorize and cooler Logs #567

Merged
merged 16 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .scalafix.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
OrganizeImports {
groupedImports = Merge
removeUnused = true
}
18 changes: 9 additions & 9 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ lazy val loggingStr = project
lazy val loggingDer = project
.in(file("logging/derivation"))
.dependsOn(loggingStr)
.dependsOn(opticsMacro % "compile->test", derivation % "compile->test")
.settings(
defaultSettings,
libraryDependencies ++= Seq(derevo, magnolia),
libraryDependencies ++= Seq(derevo, magnolia, slf4j),
publishName := "logging-derivation"
)

Expand Down Expand Up @@ -316,18 +317,17 @@ lazy val defaultScalacOptions = scalacOptions := {
}

lazy val scalacWarningConfig = scalacOptions += {
// ignore unused imports that cannot be removed due to cross-compilation
val suppressUnusedImports = Seq[String](
// put here relative file paths whose unused imports should be ignored,
// e.g. "scala/tofu/config/typesafe.scala"
).map { src =>
s"src=${scala.util.matching.Regex.quote(src)}&cat=unused-imports:iv"
}
// // ignore unused imports that cannot be removed due to cross-compilation
// val suppressUnusedImports = Seq(
// "scala/tofu/config/typesafe.scala"
// ).map { src =>
// s"src=${scala.util.matching.Regex.quote(src)}&cat=unused-imports:s"
// }.mkString(",")

// print warning category for fine-grained suppressing, e.g. @nowarn("cat=unused-params")
val verboseWarnings = "any:wv"

s"-Wconf:${(suppressUnusedImports :+ verboseWarnings).mkString(",")}"
s"-Wconf:$verboseWarnings"
}

lazy val macros = Seq(
Expand Down
1 change: 0 additions & 1 deletion config/src/main/scala/tofu/config/typesafe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import tofu.concurrent.Refs
import tofu.syntax.monadic._
import tofu.syntax.funk._
import cats.effect.SyncIO

import scala.annotation.nowarn

object typesafe {
Expand Down
19 changes: 19 additions & 0 deletions core/src/main/scala/tofu/Delay.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package tofu

import cats.effect.Sync

trait Delay[F[_]] {
def delay[A](a: => A): F[A]
}

object Delay extends CatsDelay {
type Safe[F[_, _]] = Delay[F[Nothing, *]]
type Catch[F[_, _]] = Delay[F[Throwable, *]]
}

class CatsDelay {
implicit def byCatsSync[F[_]](implicit FS: Sync[F]): Delay[F] =
new Delay[F] {
def delay[A](a: => A): F[A] = FS.delay(a)
}
}
49 changes: 25 additions & 24 deletions core/src/main/scala/tofu/bi/BiContext.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package tofu.bi

import cats.Bifunctor
import tofu.optics.Extract
import tofu.optics.Same
import tofu.optics.Contains
import tofu.bi.lift.BiUnlift
import tofu.higherKind.bi.FunBK
import tofu.control.Bind
import tofu.optics.Equivalent
import tofu.higherKind.bi.FunBK
import tofu.optics.{Contains, Equivalent, PExtract, Same}

/** typeclass for access a functional environment in a bifuntor
* @tparam X contextual error
* @tparam C contextual result
*/
trait BiContext[F[_, _], X, C] {
trait BiContext[F[+_, +_], +X, +C] {

/** base F bifunctor inclusion
*/
Expand All @@ -29,31 +26,31 @@ trait BiContext[F[_, _], X, C] {
* @param res context mapping in the optical form, this could be autogenerated `tofu.optics.Contains`
* @return focused instance of context
*/
def extract[E, A](err: Extract[X, E], res: Extract[C, A]): BiContext[F, E, A] =
def extract[E, A](err: PExtract[X, Any, E, Nothing], res: PExtract[C, Any, A, Nothing]): BiContext[F, E, A] =
new BiContextExtractInstance[F, X, C, E, A](this, err, res)

/** focus this context changing only the error
*
* @param ex error mapping in the optical form
* @return focused instance of context
*/
def lextraxt[A](ex: Extract[C, A]): BiContext[F, X, A] = extract(Same.id, ex)
def lextraxt[A](ex: PExtract[C, Any, A, Nothing]): BiContext[F, X, A] = extract(Same.id, ex)

/** focus this context changing only the result
*
* @param ex error mapping in the optical for
* @return focused instance of context
*/
def rextract[E](ex: Extract[X, E]): BiContext[F, E, C] = extract(ex, Same.id)
def rextract[E](ex: PExtract[X, Any, E, Nothing]): BiContext[F, E, C] = extract(ex, Same.id)
}

object BiContext {
def apply[F[_, _], X, C](implicit inst: BiContext[F, X, C]): BiContext[F, X, C] = inst
def apply[F[+_, +_], X, C](implicit inst: BiContext[F, X, C]): BiContext[F, X, C] = inst
}

/** typeclass for locally modification of environment for processess
*/
trait BiLocal[F[_, _], X, C] extends BiContext[F, X, C] {
trait BiLocal[F[+_, +_], X, C] extends BiContext[F, X, C] {

/** run the process in a locally modified environment
*
Expand Down Expand Up @@ -92,14 +89,14 @@ trait BiLocal[F[_, _], X, C] extends BiContext[F, X, C] {
}

object BiLocal {
def apply[F[_, _], X, C](implicit inst: BiLocal[F, X, C]): BiLocal[F, X, C] = inst
def apply[F[+_, +_], X, C](implicit inst: BiLocal[F, X, C]): BiLocal[F, X, C] = inst
}

/** typeclass relation for running processes with provided environment
* @tparam F rich process type, that requires and has access the the environment
* @tparam G base process type
*/
trait BiRun[F[_, _], G[_, _], X, C] extends BiLocal[F, X, C] with BiUnlift[G, F] {
trait BiRun[F[+_, +_], G[+_, +_], X, C] extends BiLocal[F, X, C] with BiUnlift[G, F] {
override def bifunctor: Bind[F]

/** run a process starting from the error state for the environment
Expand Down Expand Up @@ -144,35 +141,39 @@ trait BiRun[F[_, _], G[_, _], X, C] extends BiLocal[F, X, C] with BiUnlift[G, F]
def runEitherK(ctx: Either[X, C]): F FunBK G = FunBK[F](runEither(_)(ctx))

override def bilocal[E, A](fea: F[E, A])(lproj: X => X, rproj: C => C): F[E, A] =
bifunctor.foldWith[X, C, E, A](
context,
bifunctor.foldWith[X, C, E, A](context)(
x => lift(runLeft(fea)(lproj(x))),
c => lift(runRight(fea)(rproj(c)))
)

override def disclose[E, A](k: FunBK[F, G] => F[E, A]): F[E, A] =
bifunctor.foldWith[X, C, E, A](
context,
bifunctor.foldWith[X, C, E, A](context)(
x => k(FunBK.apply(runLeft(_)(x))),
c => k(FunBK.apply(runRight(_)(c)))
)
}
object BiRun {
def apply[F[_, _], G[_, _], X, C](implicit inst: BiRun[F, G, X, C]): BiRun[F, G, X, C] = inst
def apply[F[+_, +_], G[+_, +_], X, C](implicit inst: BiRun[F, G, X, C]): BiRun[F, G, X, C] = inst
}

class BiContextExtractInstance[F[_, _], X, C, E, A](ctx: BiContext[F, X, C], lext: Extract[X, E], rext: Extract[C, A])
extends BiContext[F, E, A] {
class BiContextExtractInstance[F[+_, +_], X, C, E, A](
ctx: BiContext[F, X, C],
lext: PExtract[X, Any, E, Nothing],
rext: PExtract[C, Any, A, Nothing]
) extends BiContext[F, E, A] {

override def bifunctor: Bifunctor[F] = ctx.bifunctor

override def context: F[E, A] = bifunctor.bimap(ctx.context)(lext.extract, rext.extract)

override def extract[E1, A1](err: tofu.optics.Extract[E, E1], res: tofu.optics.Extract[A, A1]): BiContext[F, E1, A1] =
ctx.extract(lext >> err, rext >> res)
override def extract[E1, A1](
err: PExtract[E, Any, E1, Nothing],
res: PExtract[A, Any, A1, Nothing]
): BiContext[F, E1, A1] =
ctx.extract(lext >> err.as[Any, Nothing], rext >> res.as[Any, Nothing])
}

class BiLocalSubInstance[F[_, _], X, C, E, A](ctx: BiLocal[F, X, C], lcts: Contains[X, E], rcts: Contains[C, A])
class BiLocalSubInstance[F[+_, +_], X, C, E, A](ctx: BiLocal[F, X, C], lcts: Contains[X, E], rcts: Contains[C, A])
extends BiContextExtractInstance[F, X, C, E, A](ctx, lcts, rcts) with BiLocal[F, E, A] {
override def bilocal[E1, A1](fea: F[E1, A1])(lproj: E => E, rproj: A => A): F[E1, A1] =
ctx.bilocal(fea)(lcts.update(_, lproj), rcts.update(_, rproj))
Expand All @@ -181,7 +182,7 @@ class BiLocalSubInstance[F[_, _], X, C, E, A](ctx: BiLocal[F, X, C], lcts: Conta
ctx.sub(lcts >> err, rcts >> res)
}

class BiRunEqvInstance[F[_, _], G[_, _], X, C, X1, C1](
class BiRunEqvInstance[F[+_, +_], G[+_, +_], X, C, X1, C1](
ctx: BiRun[F, G, X, C],
leq: Equivalent[X, X1],
req: Equivalent[C, C1]
Expand Down
9 changes: 6 additions & 3 deletions core/src/main/scala/tofu/bi/package.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package tofu

package object bi {
type UContains[F[_, _], C] = BiContext[F, Nothing, C]
type ULocal[F[_, _], C] = BiLocal[F, Nothing, C]
type URun[F[_, _], G[_, _], C] = BiRun[F, G, Nothing, C]
type UContains[F[+_, +_], +C] = BiContext[F, Nothing, C]
type ULocal[F[+_, +_], C] = BiLocal[F, Nothing, C]
type URun[F[+_, +_], G[+_, +_], C] = BiRun[F, G, Nothing, C]

type BiConst[A, B, C] = C

type TwinContext[F[+_, +_], +C] = BiContext[F, C, C]
type TwinLocal[F[+_, +_], C] = BiLocal[F, C, C]

}
3 changes: 1 addition & 2 deletions data/src/main/scala/tofu/data/Embedded.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ trait ExceptTInstances1 {

def raise[E, A](e: E): ExceptT[F, E, A] = Embedded(e.asLeftF[F, A])

def foldWith[E, A, X, R](
fa: ExceptT[F, E, A],
def foldWith[E, A, X, R](fa: ExceptT[F, E, A])(
h: E => ExceptT[F, X, R],
f: A => ExceptT[F, X, R]
): ExceptT[F, X, R] = Embedded(fa.value.flatMap {
Expand Down
5 changes: 2 additions & 3 deletions data/src/main/scala/tofu/data/calc/CalcMInstances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ class CalcBindInstance[F[+_, +_], R, S] extends StackSafeBind[CalcM[F, R, S, S,

override def raise[E, A](e: E): CalcM[F, R, S, S, E, A] = CalcM.raise(e)

override def foldWith[E, A, X, B](
fa: CalcM[F, R, S, S, E, A],
override def foldWith[E, A, X, B](fa: CalcM[F, R, S, S, E, A])(
h: E => CalcM[F, R, S, S, X, B],
f: A => CalcM[F, R, S, S, X, B]
): CalcM[F, R, S, S, X, B] = fa.foldWith(f, h)
Expand All @@ -68,7 +67,7 @@ class CalcContextInstance[F[+_, +_], R, S, E] extends WithRun[CalcM[F, R, S, S,
}

class CalcBiContextInstance[F[+_, +_], R, S]
extends BiRun[CalcM[F, R, S, S, *, *], CalcM[F, Any, S, S, *, *], Nothing, R] {
extends BiRun[CalcM[F, R, S, S, +*, +*], CalcM[F, Any, S, S, +*, +*], Nothing, R] {
override def bifunctor: Bind[CalcM[F, R, S, S, *, *]] = CalcM.calcBindInstance

override def lift[E, A](fa: CalcM[F, Any, S, S, E, A]): CalcM[F, R, S, S, E, A] = fa
Expand Down
20 changes: 0 additions & 20 deletions derivation/src/main/scala/tofu/data/derived/ContextEmbed.scala

This file was deleted.

3 changes: 2 additions & 1 deletion derivation/src/main/scala/tofu/data/derived/package.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package tofu.data

package object derived {
type Merged[A] = Merged.Mer[A]
type Merged[A] = Merged.Mer[A]
type ContextEmbed[U[f[_]]] = tofu.higherKind.derived.ContextEmbed[U]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package tofu.higherKind.derived
import cats.FlatMap
import tofu.HasContext
import tofu.bi.TwinContext
import tofu.control.Bind
import tofu.higherKind.Embed
import tofu.higherKind.bi.EmbedBK

/** simple mixin for typeclass companion
* to add contextual embedded instance
*/
trait ContextEmbed[U[f[_]]] {
final implicit def contextEmbed[F[_]: FlatMap](implicit FH: F HasContext U[F], UE: Embed[U]): U[F] =
UE.embed(FH.context)
}

/** mixin for something related to your monad
* for example context datatype companion
*/
trait EmbeddedInstances[F[_]] {
final implicit def contextEmbed[U[_[_]]](implicit FH: F HasContext U[F], UE: Embed[U], F: FlatMap[F]): U[F] =
UE.embed(FH.context)
}

/** simple mixin for typeclass companion
* to add contextual embedded instance
*/
trait ContextBiEmbed[U[f[_, _]]] {
final implicit def contextEmbed[F[+_, +_]: Bind](implicit FH: F TwinContext U[F], UE: EmbedBK[U]): U[F] =
UE.biembed[F](FH.context)
}

/** mixin for something related to your monad
* for example context datatype companion
*/
trait BiEmbeddedInstances[F[+_, +_]] {
final implicit def contextEmbed[U[f[_, _]]](implicit FH: F TwinContext U[F], UE: EmbedBK[U], F: Bind[F]): U[F] =
UE.biembed[F](FH.context)
}
5 changes: 2 additions & 3 deletions env/src/main/scala/tofu/env/bio/EnvBioInstances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import tofu.higherKind.bi.FunBK
trait EnvBioInstances {}

class EnvBioBifunctorInstance[R]
extends StackSafeBind[EnvBio[R, *, *]] with BiRun[EnvBio[R, *, *], BiTask, Nothing, R] {
extends StackSafeBind[EnvBio[R, *, *]] with BiRun[EnvBio[R, +*, +*], BiTask, Nothing, R] {

override def disclose[E, A](k: FunBK[EnvBio[R, *, *], BiTask] => EnvBio[R, E, A]): EnvBio[R, E, A] =
EnvBio.context.flatMap((ctx: R) => k(FunBK.apply(bio => bio.run(ctx))))
Expand All @@ -30,8 +30,7 @@ class EnvBioBifunctorInstance[R]

override def raise[E, A](e: E): EnvBio[R, E, A] = EnvBio.raiseError(e)

override def foldWith[E, A, X, B](
fa: EnvBio[R, E, A],
override def foldWith[E, A, X, B](fa: EnvBio[R, E, A])(
h: E => EnvBio[R, X, B],
f: A => EnvBio[R, X, B]
): EnvBio[R, X, B] = fa.foldWith(h, f)
Expand Down
2 changes: 1 addition & 1 deletion env/src/main/scala/tofu/env/bio/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package tofu.env
import monix.eval.Task

package object bio {
type BiTask[E, A] = Task[Either[E, A]]
type BiTask[+E, +A] = Task[Either[E, A]]
}
Loading