Skip to content

Commit

Permalink
Merge pull request #206 from higherkindness/gb-scala3
Browse files Browse the repository at this point in the history
  • Loading branch information
Daenyth committed Jul 20, 2021
2 parents b36c508 + 51fe47f commit ccbd2f6
Show file tree
Hide file tree
Showing 55 changed files with 1,157 additions and 429 deletions.
1 change: 1 addition & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
version = "2.7.5"
style = defaultWithAlign
maxColumn = 80

Expand Down
19 changes: 10 additions & 9 deletions athema/src/main/scala/higherkindness/athema/expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,16 @@ object Div {
private[athema] sealed trait ExprInstances {
implicit def traverseExpr[V]: Traverse[Expr[V, *]] =
new DefaultTraverse[Expr[V, *]] {
def traverse[G[_]: Applicative, A, B](fa: Expr[V, A])(
f: A => G[B]): G[Expr[V, B]] = fa match {
case v: Var[_, B @unchecked] => (v: Expr[V, B]).pure[G]
case c: Const[_, B @unchecked] => (c: Expr[V, B]).pure[G]
case e: Neg[V, A] => f(e.x) map (Neg(_))
case e: Add[V, A] => (f(e.x), f(e.y)) mapN (Add(_, _))
case e: Sub[V, A] => (f(e.x), f(e.y)) mapN (Sub(_, _))
case e: Prod[V, A] => (f(e.x), f(e.y)) mapN (Prod(_, _))
case e: Div[V, A] => (f(e.x), f(e.y)) mapN (Div(_, _))
def traverse[G[_]: Applicative, A, B](
fa: Expr[V, A]
)(f: A => G[B]): G[Expr[V, B]] = fa match {
case v: Var[V, A] => (v.asInstanceOf[Expr[V, B]]).pure[G]
case c: Const[V, A] => (c.asInstanceOf[Expr[V, B]]).pure[G]
case e: Neg[V, A] => f(e.x) map (Neg(_))
case e: Add[V, A] => (f(e.x), f(e.y)) mapN (Add(_, _))
case e: Sub[V, A] => (f(e.x), f(e.y)) mapN (Sub(_, _))
case e: Prod[V, A] => (f(e.x), f(e.y)) mapN (Prod(_, _))
case e: Div[V, A] => (f(e.x), f(e.y)) mapN (Div(_, _))
}
}
}
5 changes: 3 additions & 2 deletions athema/src/main/scala/higherkindness/athema/parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ object ExprParser {
case TSub => shunt(op, 1).flatMap(_.traverse(enqueue))
case TProd => shunt(op, 2).flatMap(_.traverse(enqueue))
case TDiv => shunt(op, 2).flatMap(_.traverse(enqueue))
}).as(tail.asLeft)
}).map(_ => tail.asLeft)
case Nil =>
for {
s0 <- StateT.get[FF, SS]
Expand Down Expand Up @@ -87,7 +87,8 @@ object ExprParser {
private def binary(
f: (
Expr.Fixed[BigDecimal],
Expr.Fixed[BigDecimal]) => Expr.Fixed[BigDecimal]
Expr.Fixed[BigDecimal]
) => Expr.Fixed[BigDecimal]
): StateT[FF, Output, Unit] =
StateT.modifyF { output0 =>
val y = output0.head
Expand Down
115 changes: 78 additions & 37 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import ProjectPlugin.ScalaV
import ProjectPlugin.on
import ProjectPlugin.onVersion

lazy val root = (project in file("."))
.settings(noPublishSettings)
.aggregate(coreJVM, coreJS)
Expand All @@ -9,7 +13,9 @@ lazy val root = (project in file("."))
.aggregate(testsJVM, testsJS)
.aggregate(athemaJVM, athemaJS)
.aggregate(readme)
.settings(crossScalaVersions := List()) // work around https://github.com/sbt/sbt/issues/4181
.settings(
crossScalaVersions := List()
) // work around https://github.com/sbt/sbt/issues/4181

lazy val publish = (project in file(".publish"))
.settings(noPublishSettings)
Expand All @@ -22,7 +28,11 @@ lazy val publish = (project in file(".publish"))
.aggregate(testsJVM, testsJS)

lazy val coverage = (project in file(".coverage"))
.settings(noPublishSettings)
.settings(
noPublishSettings,
crossScalaVersions := Seq(ScalaV.v212, ScalaV.v213),
scalaVersion := ScalaV.v213
)
.settings(coverageEnabled := true)
.aggregate(coreJVM)
.aggregate(metaJVM)
Expand All @@ -44,10 +54,14 @@ lazy val V = new {
lazy val meta = module("meta")
.settings(
mimaPreviousArtifacts := Set(
organization.value %%% moduleName.value % V.drostePrev),
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided")
organization.value %%% moduleName.value % V.drostePrev
),
libraryDependencies ++= onVersion(2)(version =>
Seq(
"org.scala-lang" % "scala-reflect" % version,
"org.scala-lang" % "scala-compiler" % version % "provided"
)
).value.flatten
)

lazy val metaJVM = meta.jvm
Expand All @@ -57,31 +71,40 @@ lazy val core = module("core")
.dependsOn(meta)
.settings(
mimaPreviousArtifacts := Set(
organization.value %%% moduleName.value % V.drostePrev),
organization.value %%% moduleName.value % V.drostePrev
),
mimaBinaryIssueFilters ++= {
import com.typesafe.tools.mima.core.IncompatibleSignatureProblem
import com.typesafe.tools.mima.core.ProblemFilters.exclude
// See https://github.com/lightbend/mima/issues/423
Seq(
exclude[IncompatibleSignatureProblem](
"higherkindness.droste.Basis#Default.unapply"),
"higherkindness.droste.Basis#Default.unapply"
),
exclude[IncompatibleSignatureProblem](
"higherkindness.droste.GAlgebra#Gathered.unapply"),
"higherkindness.droste.GAlgebra#Gathered.unapply"
),
exclude[IncompatibleSignatureProblem](
"higherkindness.droste.GAlgebraArrow.algebra"),
"higherkindness.droste.GAlgebraArrow.algebra"
),
exclude[IncompatibleSignatureProblem](
"higherkindness.droste.GAlgebraM#Gathered.unapply"),
"higherkindness.droste.GAlgebraM#Gathered.unapply"
),
exclude[IncompatibleSignatureProblem](
"higherkindness.droste.GCoalgebra#Scattered.unapply"),
"higherkindness.droste.GCoalgebra#Scattered.unapply"
),
exclude[IncompatibleSignatureProblem](
"higherkindness.droste.GCoalgebraArrow.algebra"),
"higherkindness.droste.GCoalgebraArrow.algebra"
),
exclude[IncompatibleSignatureProblem](
"higherkindness.droste.GCoalgebraM#Scattered.unapply")
"higherkindness.droste.GCoalgebraM#Scattered.unapply"
)
)
},
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-core" % V.cats,
"org.typelevel" %%% "cats-free" % V.cats)
"org.typelevel" %%% "cats-free" % V.cats
)
)

lazy val coreJVM = core.jvm
Expand All @@ -91,9 +114,21 @@ lazy val macros = module("macros")
.dependsOn(core)
.settings(
mimaPreviousArtifacts := Set(
organization.value %%% moduleName.value % V.drostePrev),
libraryDependencies ++= on(2, 12)(compilerPlugin(
"org.scalamacros" %% "paradise" % "2.1.1" cross CrossVersion.patch)).value,
organization.value %%% moduleName.value % V.drostePrev
),
libraryDependencies ++= on(2, 12)(
compilerPlugin(
"org.scalamacros" %% "paradise" % "2.1.1" cross CrossVersion.patch
)
).value,
// For some reason dependencies using `%%%` don't work with our 'on' method.
// They give 'error: Illegal dynamic dependency'
libraryDependencies ++=
(CrossVersion.partialVersion(scalaVersion.value) match {
case Some((3, _)) =>
Seq("org.typelevel" %%% "shapeless3-deriving" % "3.0.1")
case _ => Nil
}),
scalacOptions ++= on(2, 13)("-Ymacro-annotations").value
)

Expand All @@ -102,20 +137,24 @@ lazy val macrosJS = macros.js

lazy val reftree = jvmModule("reftree")
.dependsOn(coreJVM)
.settings(noScala213Settings)
.settings(
mimaPreviousArtifacts := Set(
organization.value %% moduleName.value % V.drostePrev),
libraryDependencies ++= Seq("io.github.stanch" %% "reftree" % "1.4.0")
organization.value %% moduleName.value % V.drostePrev
),
libraryDependencies ++= on(2, 12)(
"io.github.stanch" %% "reftree" % "1.4.0"
).value
)

lazy val scalacheck = module("scalacheck")
.dependsOn(core)
.settings(
mimaPreviousArtifacts := Set(
organization.value %%% moduleName.value % V.drostePrev),
organization.value %%% moduleName.value % V.drostePrev
),
libraryDependencies ++= Seq(
"org.scalacheck" %%% "scalacheck" % V.scalacheck)
"org.scalacheck" %%% "scalacheck" % V.scalacheck
)
)

lazy val scalacheckJVM = scalacheck.jvm
Expand All @@ -125,9 +164,11 @@ lazy val laws = module("laws")
.dependsOn(core)
.settings(
mimaPreviousArtifacts := Set(
organization.value %%% moduleName.value % V.drostePrev),
organization.value %%% moduleName.value % V.drostePrev
),
libraryDependencies ++= Seq(
"org.scalacheck" %%% "scalacheck" % V.scalacheck)
"org.scalacheck" %%% "scalacheck" % V.scalacheck
)
)

lazy val lawsJVM = laws.jvm
Expand All @@ -145,9 +186,14 @@ lazy val tests = module("tests")
"eu.timepit" %%% "refined-scalacheck" % V.refined,
"org.scala-lang.modules" %%% "scala-collection-compat" % V.collectionCompat % Test
),
libraryDependencies ++= on(2, 12)(compilerPlugin(
"org.scalamacros" %% "paradise" % "2.1.1" cross CrossVersion.patch)).value,
scalacOptions ++= on(2, 13)("-Ymacro-annotations").value
libraryDependencies ++= on(2, 12)(
compilerPlugin(
"org.scalamacros" %% "paradise" % "2.1.1" cross CrossVersion.patch
)
).value,
scalacOptions ++= on(2, 13)("-Ymacro-annotations").value,
// 'nowarn' doesn't work on scala3 yet, make warnings not fatal.
scalacOptions --= on(3)("-Xfatal-warnings").value
)

lazy val testsJVM = tests.jvm
Expand All @@ -165,7 +211,10 @@ lazy val athema = module("athema", prefix = "")
) ++
Seq(
"org.scalacheck" %%% "scalacheck" % V.scalacheck
).map(_ % "test"))
).map(_ % "test"),
// 'nowarn' doesn't work on scala3 yet, make warnings not fatal.
scalacOptions --= on(3)("-Xfatal-warnings").value
)

lazy val athemaJVM = athema.jvm
lazy val athemaJS = athema.js
Expand Down Expand Up @@ -203,12 +252,4 @@ addCommandAlias(
)
addCommandAlias("ci-docs", ";github;mdoc")

def on[A](major: Int, minor: Int)(a: A): Def.Initialize[Seq[A]] =
Def.setting {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some(v) if v == (major, minor) => Seq(a)
case _ => Nil
}
}

ThisBuild / resolvers += Resolver.sonatypeRepo("public")
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import cats.syntax.functor._
import cats.syntax.traverse._

import meta.Meta
import data.prelude._
import util.DefaultTraverse
import higherkindness.droste.data.prelude._
import higherkindness.droste.util.DefaultTraverse

object AttrF {
def apply[F[_], A, B](ask: A, lower: F[B]): AttrF[F, A, B] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import cats.syntax.functor._
import cats.syntax.traverse._

import meta.Meta
import util.DefaultTraverse
import higherkindness.droste.util.DefaultTraverse

object CoattrF {
def apply[F[_], A, B](f: Either[A, F[B]]): CoattrF[F, A, B] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ object Fix {

def algebra[F[_]]: Algebra[F, Fix[F]] = Algebra(apply(_))
def coalgebra[F[_]]: Coalgebra[F, Fix[F]] = Coalgebra(un(_))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package higherkindness.droste
package data

import cats.Comonad
import cats.Eval
import cats.Functor

import cats.syntax.functor._

import prelude._

object Attr {
def apply[F[_], A](head: A, tail: F[Attr[F, A]]): Attr[F, A] =
apply((head, tail))
def apply[F[_], A](f: (A, F[Attr[F, A]])): Attr[F, A] = f.asInstanceOf
def un[F[_], A](f: Attr[F, A]): (A, F[Attr[F, A]]) = f.asInstanceOf
def unapply[F[_], A](f: Attr[F, A]): Some[(A, F[Attr[F, A]])] = Some(un(f))

def algebra[F[_], A]: Algebra[AttrF[F, A, *], Attr[F, A]] =
Algebra(fa => Attr(AttrF.un(fa)))

def coalgebra[F[_], A]: Coalgebra[AttrF[F, A, *], Attr[F, A]] =
Coalgebra(a => AttrF(Attr.un(a)))

def fromCats[F[_]: Functor, A](cofree: cats.free.Cofree[F, A]): Attr[F, A] =
ana(cofree)(_.tail.value, _.head)

def unfold[F[_]: Functor, A](a: A)(coalgebra: A => F[A]): Attr[F, A] =
ana(a)(coalgebra, identity)

/** An inlined anamorphism to `Attr` with a fused map */
def ana[F[_]: Functor, A, C](
a: A
)(coalgebra: A => F[A], f: A => C): Attr[F, C] =
Attr(f(a), coalgebra(a).map(ana(_)(coalgebra, f)))
}

private[data] trait AttrImplicits {
implicit final class AttrOps[F[_], A](attr: Attr[F, A]) {
def tuple: (A, F[Attr[F, A]]) = Attr.un(attr)
def head: A = tuple._1
def tail: F[Attr[F, A]] = tuple._2

def toCats(implicit ev: Functor[F]): cats.free.Cofree[F, A] =
cats.free.Cofree(head, Eval.later(tail.map(_.toCats)))

def forget(implicit ev: Functor[F]): Fix[F] =
Fix(tail.map(_.forget))
}

implicit def drosteAttrComonad[F[_]: Functor]: Comonad[Attr[F, *]] =
new AttrComonad[F]
}

private[data] final class AttrComonad[F[_]: Functor]
extends Comonad[Attr[F, *]] {
def coflatMap[A, B](fa: Attr[F, A])(f: Attr[F, A] => B): Attr[F, B] =
Attr.ana(fa)(_.tail, f)

def extract[A](fa: Attr[F, A]): A = fa.head

def map[A, B](fa: Attr[F, A])(f: A => B): Attr[F, B] =
Attr(f(fa.head), fa.tail.map(_.map(f)))
}

0 comments on commit ccbd2f6

Please sign in to comment.