diff --git a/build.sbt b/build.sbt index 0b30468..18b7947 100644 --- a/build.sbt +++ b/build.sbt @@ -19,6 +19,7 @@ lazy val core = crossProject(JVMPlatform, JSPlatform) .crossType(CrossType.Pure) .in(file("core")) .settings(yPartial) + .settings(yKindProjector) .settings( name := "rediculous", mimaPreviousArtifacts := Set(), // Bincompat breaking till next release @@ -87,4 +88,16 @@ lazy val yPartial = if (scalaVersion.value.startsWith("2.12")) Seq("-Ypartial-unification") else Seq() } - ) \ No newline at end of file + ) + +lazy val yKindProjector = + Seq( + scalacOptions ++= { + if(scalaVersion.value.startsWith("3")) Seq("-Ykind-projector") + else Seq() + }, + libraryDependencies ++= { + if(scalaVersion.value.startsWith("3")) Seq() + else Seq(compilerPlugin("org.typelevel" % "kind-projector" % "0.13.2" cross CrossVersion.full)) + } + ) diff --git a/core/src/main/scala/io/chrisdavenport/rediculous/Redis.scala b/core/src/main/scala/io/chrisdavenport/rediculous/Redis.scala index e040d04..10e7874 100644 --- a/core/src/main/scala/io/chrisdavenport/rediculous/Redis.scala +++ b/core/src/main/scala/io/chrisdavenport/rediculous/Redis.scala @@ -48,14 +48,14 @@ object Redis { def unwrap[F[_], A](fa: Type[F, A]): Redis[F, A] = fa.asInstanceOf[Redis[F, A]] - def parallel[F[_]]: ({ type M[A] = Redis[F, A] })#M ~> ({ type M[A] = Par[F, A] })#M = new ~>[({ type M[A] = Redis[F, A] })#M, ({ type M[A] = Par[F, A] })#M]{ + def parallel[F[_]]: Redis[F, *] ~> Par[F, *] = new ~>[Redis[F, *], Par[F, *]]{ def apply[A](fa: Redis[F,A]): Par[F,A] = Par(fa) } - def sequential[F[_]]: ({ type M[A] = Par[F, A] })#M ~> ({ type M[A] = Redis[F, A] })#M = new ~>[({ type M[A] = Par[F, A] })#M, ({ type M[A] = Redis[F, A] })#M]{ + def sequential[F[_]]: Par[F, *] ~> Redis[F, *] = new ~>[Par[F, *], Redis[F, *]]{ def apply[A](fa: Par[F,A]): Redis[F,A] = unwrap(fa) } - implicit def parApplicative[F[_]: Parallel: Monad]: Applicative[({ type M[A] = Par[F, A] })#M] = new Applicative[({ type M[A] = Par[F, A] })#M]{ + implicit def parApplicative[F[_]: Parallel: Monad]: Applicative[Par[F, *]] = new Applicative[Par[F, *]]{ def ap[A, B](ff: Par[F,A => B])(fa: Par[F,A]): Par[F,B] = Par(Redis{ val kfx : Kleisli[F, RedisConnection[F], A => B] = Par.unwrap(ff).unRedis val kfa : Kleisli[F, RedisConnection[F], A] = Par.unwrap(fa).unRedis @@ -68,10 +68,10 @@ object Redis { } - implicit def monad[F[_]: Monad]: Monad[({ type M[A] = Redis[F, A] })#M] = new Monad[({ type M[A] = Redis[F, A] })#M]{ + implicit def monad[F[_]: Monad]: Monad[Redis[F, *]] = new Monad[Redis[F, *]]{ def tailRecM[A, B](a: A)(f: A => Redis[F,Either[A,B]]): Redis[F,B] = Redis( - Monad[({ type M[A] = Kleisli[F, RedisConnection[F], A]})#M].tailRecM[A, B](a)(f.andThen(_.unRedis.flatMap(fe => Kleisli.liftF(fe.pure[F])))) + Monad[Kleisli[F, RedisConnection[F], *]].tailRecM[A, B](a)(f.andThen(_.unRedis.flatMap(fe => Kleisli.liftF(fe.pure[F])))) ) def flatMap[A, B](fa: Redis[F,A])(f: A => Redis[F,B]): Redis[F,B] = Redis( @@ -84,17 +84,17 @@ object Redis { ) } - implicit def parRedis[M[_]: Parallel: Concurrent]: Parallel[({ type L[A] = Redis[M, A] })#L] = new Parallel[({ type L[A] = Redis[M, A] })#L]{ + implicit def parRedis[M[_]: Parallel: Concurrent]: Parallel[Redis[M, *]] = new Parallel[Redis[M, *]]{ type F[A] = Par[M, A] - def sequential: F ~> ({ type L[X] = Redis[M, X] })#L = + def sequential: F ~> Redis[M, *] = Par.sequential[M] - def parallel: ({ type L[A] = Redis[M, A] })#L ~> F = Par.parallel[M] + def parallel: Redis[M, *] ~> F = Par.parallel[M] def applicative: Applicative[F] = Par.parApplicative[M] - def monad: Monad[({ type L[A] = Redis[M, A] })#L] = Redis.monad[M] + def monad: Monad[Redis[M, *]] = Redis.monad[M] } } \ No newline at end of file diff --git a/core/src/main/scala/io/chrisdavenport/rediculous/RedisConnection.scala b/core/src/main/scala/io/chrisdavenport/rediculous/RedisConnection.scala index dbb7832..03d355d 100644 --- a/core/src/main/scala/io/chrisdavenport/rediculous/RedisConnection.scala +++ b/core/src/main/scala/io/chrisdavenport/rediculous/RedisConnection.scala @@ -54,7 +54,7 @@ object RedisConnection{ def withSocket(socket: Socket[F]): F[Chunk[Resp]] = explicitPipelineRequest[F](socket, chunk) connection match { - case PooledConnection(pool) => Functor[({type M[A] = KeyPool[F, Unit, A]})#M].map(pool)(_._1).take(()).use{ + case PooledConnection(pool) => Functor[KeyPool[F, Unit, *]].map(pool)(_._1).take(()).use{ m => withSocket(m.value).attempt.flatTap{ case Left(_) => m.canBeReused.set(Reusable.DontReuse) case _ => Applicative[F].unit @@ -273,7 +273,7 @@ object RedisConnection{ Stream.fromQueueUnterminatedChunk(queue, chunkSizeLimit).chunks.map{chunk => val s = if (chunk.nonEmpty) { Stream.eval( - Functor[({type M[A] = KeyPool[F, Unit, A]})#M].map(keypool)(_._1).take(()).attempt.use{ + Functor[KeyPool[F, Unit, *]].map(keypool)(_._1).take(()).attempt.use{ case Right(m) => val out = chunk.map(_._2) explicitPipelineRequest(m.value, out).attempt.flatTap{// Currently Guarantee Chunk.size === returnSize @@ -299,7 +299,7 @@ object RedisConnection{ .compile .drain .background - } yield Queued(queue, keypool.take(()).map(Functor[({type M[A] = Managed[F, A]})#M].map(_)(_._1))) + } yield Queued(queue, keypool.take(()).map(Functor[Managed[F, *]].map(_)(_._1))) } } @@ -384,7 +384,7 @@ object RedisConnection{ ).build // Cluster Topology Acquisition and Management - sockets <- Resource.eval(keypool.take((host, port)).map(_.value._1).map(DirectConnection(_)).use(ClusterCommands.clusterslots[({ type M[A] = Redis[F, A] })#M].run(_))) + sockets <- Resource.eval(keypool.take((host, port)).map(_.value._1).map(DirectConnection(_)).use(ClusterCommands.clusterslots[Redis[F, *]].run(_))) now <- Resource.eval(Temporal[F].realTime.map(_.toMillis)) refreshLock <- Resource.eval(Semaphore[F](1L)) refTopology <- Resource.eval(Ref[F].of((sockets, now))) @@ -403,7 +403,7 @@ object RedisConnection{ case ((_, setAt), now) if setAt >= (now - cacheTopologySeconds.toMillis) => Applicative[F].unit case ((l, _), _) => val nelActions: NonEmptyList[F[ClusterSlots]] = l.map{ case (host, port) => - keypool.take((host, port)).map(_.value._1).map(DirectConnection(_)).use(ClusterCommands.clusterslots[({ type M[A] = Redis[F, A] })#M].run(_)) + keypool.take((host, port)).map(_.value._1).map(DirectConnection(_)).use(ClusterCommands.clusterslots[Redis[F, *]].run(_)) } raceNThrowFirst(nelActions) .flatMap(s => Clock[F].realTime.map(_.toMillis).flatMap(now => refTopology.set((s,now)))) @@ -422,7 +422,7 @@ object RedisConnection{ }.toSeq ).evalMap{ case (server, rest) => - Functor[({type M[A] = KeyPool[F, (Host, Port), A]})#M].map(keypool)(_._1).take(server).attempt.use{ + Functor[KeyPool[F, (Host, Port), *]].map(keypool)(_._1).take(server).attempt.use{ case Right(m) => val out = Chunk.seq(rest.map(_._5)) explicitPipelineRequest(m.value, out).attempt.flatTap{// Currently Guarantee Chunk.size === returnSize diff --git a/core/src/main/scala/io/chrisdavenport/rediculous/RedisCtx.scala b/core/src/main/scala/io/chrisdavenport/rediculous/RedisCtx.scala index 6e9f7f0..c0dc79a 100644 --- a/core/src/main/scala/io/chrisdavenport/rediculous/RedisCtx.scala +++ b/core/src/main/scala/io/chrisdavenport/rediculous/RedisCtx.scala @@ -22,7 +22,7 @@ object RedisCtx { def apply[F[_]](implicit ev: RedisCtx[F]): ev.type = ev - implicit def redis[F[_]: Concurrent]: RedisCtx[({ type M[A] = Redis[F, A] })#M] = new RedisCtx[({ type M[A] = Redis[F, A] })#M]{ + implicit def redis[F[_]: Concurrent]: RedisCtx[Redis[F, *]] = new RedisCtx[Redis[F, *]]{ def keyed[A: RedisResult](key: String, command: NonEmptyList[String]): Redis[F,A] = RedisConnection.runRequestTotal(command, Some(key)) def unkeyed[A: RedisResult](command: NonEmptyList[String]): Redis[F, A] = diff --git a/core/src/main/scala/io/chrisdavenport/rediculous/RedisPubSub.scala b/core/src/main/scala/io/chrisdavenport/rediculous/RedisPubSub.scala index bc140d1..461fdf6 100644 --- a/core/src/main/scala/io/chrisdavenport/rediculous/RedisPubSub.scala +++ b/core/src/main/scala/io/chrisdavenport/rediculous/RedisPubSub.scala @@ -93,7 +93,7 @@ object RedisPubSub { val pSubPrefix = "ps:" def publish(s: String, message: String): F[Int] = - RedisCtx[({type M[A] = Redis[F, A]})#M].unkeyed[Int](cats.data.NonEmptyList.of("PUBLISH", s, message)).run(connection) + RedisCtx[Redis[F, *]].unkeyed[Int](cats.data.NonEmptyList.of("PUBLISH", s, message)).run(connection) def unsubscribeAll: F[Unit] = cbStorage.get.map(_.keys.toList).flatMap{list => val channelSubscriptions = list.collect{ case x if x.startsWith("c") => x.drop(3)} diff --git a/core/src/main/scala/io/chrisdavenport/rediculous/RedisTransaction.scala b/core/src/main/scala/io/chrisdavenport/rediculous/RedisTransaction.scala index 9d6c299..5391dbf 100644 --- a/core/src/main/scala/io/chrisdavenport/rediculous/RedisTransaction.scala +++ b/core/src/main/scala/io/chrisdavenport/rediculous/RedisTransaction.scala @@ -83,7 +83,7 @@ object RedisTransaction { object RedisTxState { implicit val m: Monad[RedisTxState] = new StackSafeMonad[RedisTxState]{ - def pure[A](a: A): RedisTxState[A] = RedisTxState(Monad[({ type F[A] = State[(Int, List[NonEmptyList[String]], Option[String]), A]})#F].pure(a)) + def pure[A](a: A): RedisTxState[A] = RedisTxState(Monad[State[(Int, List[NonEmptyList[String]], Option[String]), *]].pure(a)) def flatMap[A, B](fa: RedisTxState[A])(f: A => RedisTxState[B]): RedisTxState[B] = RedisTxState( fa.value.flatMap(f.andThen(_.value)) ) @@ -108,10 +108,10 @@ object RedisTransaction { // Operations // ---------- def watch[F[_]: Concurrent](keys: List[String]): Redis[F, Status] = - RedisCtx[({ type M[A] = Redis[F, A] })#M].unkeyed(NonEmptyList("WATCH", keys)) + RedisCtx[Redis[F, *]].unkeyed(NonEmptyList("WATCH", keys)) def unwatch[F[_]: Concurrent]: Redis[F, Status] = - RedisCtx[({ type M[A] = Redis[F, A] })#M].unkeyed(NonEmptyList.of("UNWATCH")) + RedisCtx[Redis[F, *]].unkeyed(NonEmptyList.of("UNWATCH")) def multiExec[F[_]] = new MultiExecPartiallyApplied[F]