From bd1be196a879240379a3a6df143e8b019815cf08 Mon Sep 17 00:00:00 2001 From: Alexandre Moreno Date: Sun, 7 Jan 2024 10:15:57 +0100 Subject: [PATCH] improve type inference of NonDet handlers --- core/src/main/scala/evidence/effect/NonDet.scala | 13 ++++++++++++- examples/src/main/scala/Example.scala | 14 +++++++------- examples/src/main/scala/Parse.scala | 8 ++------ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/core/src/main/scala/evidence/effect/NonDet.scala b/core/src/main/scala/evidence/effect/NonDet.scala index 9b52dea..cbc120e 100644 --- a/core/src/main/scala/evidence/effect/NonDet.scala +++ b/core/src/main/scala/evidence/effect/NonDet.scala @@ -5,6 +5,8 @@ import cats.Alternative import cats.Monad import cats.implicits._ import evidence.Ctx.In +import cats.Foldable +import cats.MonoidK type NonDet = [E, Ans] =>> NonDet.Syn[E, Ans] @@ -33,7 +35,11 @@ object NonDet: NonDet.choose.ifM(x, y) } - def allResults[E, A, F[_]](using + def choice[E, A, G[_]]( + ps: G[Eff[E, A]] + )(using G: Foldable[G], F: MonoidK[Eff[E, *]]): Eff[E, A] = G.foldK(ps) + + def amb[E, A, F[_]](using F: Alternative[F] ): Eff[NonDet :* E, A] => Eff[E, F[A]] = Eff.handlerRet( @@ -49,3 +55,8 @@ object NonDet: , _ ) + + def allResults[E, A]: Eff[NonDet :* E, A] => Eff[E, List[A]] = amb[E, A, List] + + def firstResult[E, A]: Eff[NonDet :* E, A] => Eff[E, Option[A]] = + amb[E, A, Option] diff --git a/examples/src/main/scala/Example.scala b/examples/src/main/scala/Example.scala index a921375..e618c4d 100644 --- a/examples/src/main/scala/Example.scala +++ b/examples/src/main/scala/Example.scala @@ -124,7 +124,7 @@ object Example: y <- NonDet.choose yield (x && !y) || (!x && y) - println(NonDet.allResults[Nothing, Boolean, Vector](xor).run) + println(NonDet.allResults(xor).run) def branches[F[_]: Monad](using F: MonoidK[F], @@ -135,9 +135,9 @@ object Example: y <- G.foldK(List(4, 5, 6).map(_.pure[F])) yield (x, y) - println(branches[Vector]) + println(branches[List]) - println(NonDet.allResults[Nothing, (Int, Int), Vector](branches).run) + println(NonDet.allResults(branches).run) // def logging[F[_]: Monad](implicit F: Tell[F, Log]): F[Unit] = // // Example of some logging activity in your application @@ -180,7 +180,7 @@ object Example: println( NonDet - .allResults[Nothing, (Int, String), Option]( + .firstResult( Parse.parse("999")(Parse.digit) ) .run @@ -191,7 +191,7 @@ object Example: println( NonDet - .allResults[Nothing, (Int, String), Option]( + .firstResult( Parse.parse("[12345678]")( brackets(Parse.number) ) @@ -201,9 +201,9 @@ object Example: println( NonDet - .allResults[Nothing, (String, String), Option]( + .firstResult( Parse.parse("bazz")( - Parse.choice( + NonDet.choice( Parse.string("foo") :: Parse .string("bar") :: Parse.string("baz") :: Nil ) diff --git a/examples/src/main/scala/Parse.scala b/examples/src/main/scala/Parse.scala index db73c8d..c23e6ff 100644 --- a/examples/src/main/scala/Parse.scala +++ b/examples/src/main/scala/Parse.scala @@ -4,10 +4,10 @@ import evidence.* import evidence.effect.* import cats.implicits._ import evidence.effect.NonDet.given -import cats.Alternative import cats.Monad import cats.MonoidK import cats.Foldable +import cats.Alternative type Parse = [E, Ans] =>> Parse.Syn[E, Ans] @@ -24,7 +24,7 @@ object Parse: )(p) def many[E, A](p: Eff[E, A]): NonDet :? E ?=> Eff[E, List[A]] = - Alternative[Eff[E, *]].combineK(many1(p), List.empty[A].pure) + Alternative[Eff[E, *]].combineK(many1(p), Nil.pure) def many1[E, A](p: Eff[E, A]): NonDet :? E ?=> Eff[E, List[A]] = for @@ -32,10 +32,6 @@ object Parse: xs <- many(p) yield x :: xs - def choice[F[_]: Monad, G[_], A]( - ps: G[F[A]] - )(using F: MonoidK[F], G: Foldable[G]): F[A] = G.foldK(ps) - def parse[E, A]( input: String ): NonDet :? E ?=> Eff[Parse :* E, A] => Eff[E, (A, String)] =