From 4294484248708b51213773da60a5cc9b3afe2213 Mon Sep 17 00:00:00 2001 From: Anton Voitsishevskii Date: Mon, 29 Aug 2022 10:55:00 +0300 Subject: [PATCH 1/5] add discard method; --- examples/src/main/resources/logback.groovy | 19 ------------------- .../src/main/scala/tofu/syntax/monadic.scala | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 19 deletions(-) delete mode 100644 examples/src/main/resources/logback.groovy diff --git a/examples/src/main/resources/logback.groovy b/examples/src/main/resources/logback.groovy deleted file mode 100644 index 18ab22e3e..000000000 --- a/examples/src/main/resources/logback.groovy +++ /dev/null @@ -1,19 +0,0 @@ -import tofu.logging.logback.ConsoleContextLayout -import tofu.logging.ELKLayout - -//puts messages as plain text -appender("PLAIN-COLORED", ConsoleAppender) { - encoder(LayoutWrappingEncoder) { - layout(ConsoleContextLayout) { - pattern = "%cyan(%d{HH:mm:ss} %-5level %logger{36} - %msg%n [%mdc]%n)" - } - } -} -//puts messages as JSONs -appender("STRUCTURED", ConsoleAppender) { - encoder(LayoutWrappingEncoder) { - layout(ELKLayout) - } -} - -root(DEBUG, ["PLAIN-COLORED", "STRUCTURED"]) \ No newline at end of file diff --git a/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala b/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala index edbba3d35..43c13a464 100644 --- a/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala +++ b/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala @@ -7,6 +7,22 @@ object monadic extends TupleSemigroupalSyntax with ApplicativeSyntax with MonadS def unit[F[_]](implicit F: Applicative[F]): F[Unit] = F.unit implicit final class TofuFunctorOps[F[_], A](private val fa: F[A]) extends AnyVal { + /** Safer way than [[void]] to discard a value + * + * Explicit type ascription eliminates a bug when one can begin discarding non-discard-able value. + * + * @example + * {{{ + * val computation1: F[Thing] = ??? + * val result11: F[Unit] = computation.void + * val result12: F[Unit] = computation.discard[Thing] + * + * //after changes or refactoring + * val computation2: F[F[Thing]] = ??? + * val result21: F[Unit] = computation.void //error here, nested F is not evaluated and compiler doesn't warn + * val result22: F[Unit] = computation.discard[Thing] //compiler produces an error + * }}} */ + def discard[AA](implicit ev: AA =:= A, F: Functor[F]): F[Unit] = F.void(fa) def map[B](f: A => B)(implicit F: Functor[F]): F[B] = F.map(fa)(f) def fmap[B](f: A => B)(implicit F: Functor[F]): F[B] = F.fmap(fa)(f) def widen[B >: A](implicit F: Functor[F]): F[B] = F.widen(fa) From 3ddbb2afa0096e5e799798a6205e6a115225c847 Mon Sep 17 00:00:00 2001 From: Anton Voitsishevskii Date: Mon, 29 Aug 2022 10:57:11 +0300 Subject: [PATCH 2/5] bring back accidentally deleted file; --- examples/src/main/resources/logback.groovy | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 examples/src/main/resources/logback.groovy diff --git a/examples/src/main/resources/logback.groovy b/examples/src/main/resources/logback.groovy new file mode 100644 index 000000000..18ab22e3e --- /dev/null +++ b/examples/src/main/resources/logback.groovy @@ -0,0 +1,19 @@ +import tofu.logging.logback.ConsoleContextLayout +import tofu.logging.ELKLayout + +//puts messages as plain text +appender("PLAIN-COLORED", ConsoleAppender) { + encoder(LayoutWrappingEncoder) { + layout(ConsoleContextLayout) { + pattern = "%cyan(%d{HH:mm:ss} %-5level %logger{36} - %msg%n [%mdc]%n)" + } + } +} +//puts messages as JSONs +appender("STRUCTURED", ConsoleAppender) { + encoder(LayoutWrappingEncoder) { + layout(ELKLayout) + } +} + +root(DEBUG, ["PLAIN-COLORED", "STRUCTURED"]) \ No newline at end of file From f7c3f859c3c794908c64f4a234c4da5028565191 Mon Sep 17 00:00:00 2001 From: Anton Voitsishevskii Date: Mon, 29 Aug 2022 11:07:36 +0300 Subject: [PATCH 3/5] fix typos in scaladoc; --- .../src/main/scala/tofu/syntax/monadic.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala b/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala index 43c13a464..b299c8c3d 100644 --- a/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala +++ b/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala @@ -14,13 +14,13 @@ object monadic extends TupleSemigroupalSyntax with ApplicativeSyntax with MonadS * @example * {{{ * val computation1: F[Thing] = ??? - * val result11: F[Unit] = computation.void - * val result12: F[Unit] = computation.discard[Thing] + * val result11: F[Unit] = computation1.void + * val result12: F[Unit] = computation1.discard[Thing] * * //after changes or refactoring * val computation2: F[F[Thing]] = ??? - * val result21: F[Unit] = computation.void //error here, nested F is not evaluated and compiler doesn't warn - * val result22: F[Unit] = computation.discard[Thing] //compiler produces an error + * val result21: F[Unit] = computation2.void //error here, nested F is not evaluated and compiler doesn't warn + * val result22: F[Unit] = computation2.discard[Thing] //compiler produces an error * }}} */ def discard[AA](implicit ev: AA =:= A, F: Functor[F]): F[Unit] = F.void(fa) def map[B](f: A => B)(implicit F: Functor[F]): F[B] = F.map(fa)(f) From 032d9516fda7de27da7eae2817f1448069393ad6 Mon Sep 17 00:00:00 2001 From: Anton Voitsishevskii Date: Mon, 29 Aug 2022 14:10:33 +0300 Subject: [PATCH 4/5] fix typos in scaladoc; --- .../test/scala/tofu/syntax/monadicSpec.scala | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 modules/higherKindCore/src/test/scala/tofu/syntax/monadicSpec.scala diff --git a/modules/higherKindCore/src/test/scala/tofu/syntax/monadicSpec.scala b/modules/higherKindCore/src/test/scala/tofu/syntax/monadicSpec.scala new file mode 100644 index 000000000..d478333c9 --- /dev/null +++ b/modules/higherKindCore/src/test/scala/tofu/syntax/monadicSpec.scala @@ -0,0 +1,17 @@ +package tofu.syntax + +import org.scalatest.funsuite.AnyFunSuite +import tofu.syntax.monadic._ + +class monadicSpec extends AnyFunSuite { + trait Thing + test("discard should properly discard values") { + val value: Option[Int] = Some(4) + val nestedValue: Option[Option[Int]] = Some(Some(3)) + + assertResult(value.discard[Int])(Some(())) + assertResult(value.discard)(Some(())) + assertDoesNotCompile("nestedValue.discard[Int]") + assertResult(nestedValue.discard)(Some(())) + } +} From c820a1b22bc783f935fbda8ceb715dce2d3fe2f9 Mon Sep 17 00:00:00 2001 From: Anton Voitsishevskii Date: Mon, 29 Aug 2022 14:10:54 +0300 Subject: [PATCH 5/5] add small spec for monadic.discard; --- .../src/main/scala/tofu/syntax/monadic.scala | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala b/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala index b299c8c3d..3dbbc5bf4 100644 --- a/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala +++ b/modules/higherKindCore/src/main/scala/tofu/syntax/monadic.scala @@ -7,12 +7,13 @@ object monadic extends TupleSemigroupalSyntax with ApplicativeSyntax with MonadS def unit[F[_]](implicit F: Applicative[F]): F[Unit] = F.unit implicit final class TofuFunctorOps[F[_], A](private val fa: F[A]) extends AnyVal { + /** Safer way than [[void]] to discard a value * * Explicit type ascription eliminates a bug when one can begin discarding non-discard-able value. * * @example - * {{{ + * {{{ * val computation1: F[Thing] = ??? * val result11: F[Unit] = computation1.void * val result12: F[Unit] = computation1.discard[Thing] @@ -21,16 +22,17 @@ object monadic extends TupleSemigroupalSyntax with ApplicativeSyntax with MonadS * val computation2: F[F[Thing]] = ??? * val result21: F[Unit] = computation2.void //error here, nested F is not evaluated and compiler doesn't warn * val result22: F[Unit] = computation2.discard[Thing] //compiler produces an error - * }}} */ + * }}} + */ def discard[AA](implicit ev: AA =:= A, F: Functor[F]): F[Unit] = F.void(fa) - def map[B](f: A => B)(implicit F: Functor[F]): F[B] = F.map(fa)(f) - def fmap[B](f: A => B)(implicit F: Functor[F]): F[B] = F.fmap(fa)(f) - def widen[B >: A](implicit F: Functor[F]): F[B] = F.widen(fa) - def void(implicit F: Functor[F]): F[Unit] = F.void(fa) - def fproduct[B](f: A => B)(implicit F: Functor[F]): F[(A, B)] = F.fproduct(fa)(f) - def as[B](b: B)(implicit F: Functor[F]): F[B] = F.as(fa, b) - def tupleLeft[B](b: B)(implicit F: Functor[F]): F[(B, A)] = F.tupleLeft(fa, b) - def tupleRight[B](b: B)(implicit F: Functor[F]): F[(A, B)] = F.tupleRight(fa, b) + def map[B](f: A => B)(implicit F: Functor[F]): F[B] = F.map(fa)(f) + def fmap[B](f: A => B)(implicit F: Functor[F]): F[B] = F.fmap(fa)(f) + def widen[B >: A](implicit F: Functor[F]): F[B] = F.widen(fa) + def void(implicit F: Functor[F]): F[Unit] = F.void(fa) + def fproduct[B](f: A => B)(implicit F: Functor[F]): F[(A, B)] = F.fproduct(fa)(f) + def as[B](b: B)(implicit F: Functor[F]): F[B] = F.as(fa, b) + def tupleLeft[B](b: B)(implicit F: Functor[F]): F[(B, A)] = F.tupleLeft(fa, b) + def tupleRight[B](b: B)(implicit F: Functor[F]): F[(A, B)] = F.tupleRight(fa, b) } implicit final class TofuSemigroupalOps[F[_], A](private val fa: F[A]) extends AnyVal {