Skip to content

Commit

Permalink
Merge pull request #28 from andyscott/cleanup
Browse files Browse the repository at this point in the history
Minor cleanup; Add ability to unfold to cats.free.Cofree
  • Loading branch information
andyscott authored Jul 8, 2018
2 parents 36df1ac + 6527231 commit 1e5bebb
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 22 deletions.
3 changes: 2 additions & 1 deletion athema/src/main/scala/qq/athema/expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package qq.athema
import cats.Applicative
import cats.Traverse
import cats.syntax.all._
import qq.droste._

import qq.droste.data._
import qq.droste.util.DefaultTraverse

sealed trait Expr[V, A]
final case class Var [V, A](name: String) extends Expr[V, A] {
Expand Down
16 changes: 13 additions & 3 deletions modules/core/src/main/scala/qq/droste/basis.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package qq.droste

import data.prelude._
import data.Cofree
import data.EnvT
import data.Fix

import cats.Eval

trait Embed[F[_], R] {
def algebra: Algebra[F, R]
}
Expand Down Expand Up @@ -40,7 +43,6 @@ object Basis extends FloatingBasisInstances[Basis] {
type PatF[F[_], A] = PF[F, A]
}
}

}

private[droste] sealed trait FloatingBasisInstances[H[F[_], A] >: Basis[F, A]] extends FloatingBasisInstances0[H] {
Expand All @@ -51,9 +53,17 @@ private[droste] sealed trait FloatingBasisInstances[H[F[_], A] >: Basis[F, A]] e
private[droste] sealed trait FloatingBasisInstances0[H[F[_], A] >: Basis[F, A]] {
implicit def drosteBasisForFix[F[_]]: H[F, Fix[F]] =
Basis.Default[F, Fix[F]](Fix.algebra, Fix.coalgebra)

implicit def drosteBasisForCatsCofree[F[_], E]: H[EnvT[E, F, ?], cats.free.Cofree[F, E]] =
Basis.Default[EnvT[E, F, ?], cats.free.Cofree[F, E]](
fa => cats.free.Cofree(fa.ask, Eval.now(fa.lower)),
a => EnvT(a.head, a.tailForced))
}

private[droste] sealed trait FloatingBasisSolveInstances {
implicit val drosteSolveFix : Basis.Solve.Aux[Fix, λ[(F[_], α) => F[α]]] = null
implicit def drosteSolveCofree[E]: Basis.Solve.Aux[Cofree[?[_], E], EnvT[E, ?[_], ?]] = null
import Basis.Solve

implicit val drosteSolveFix: Solve.Aux[Fix, λ[(F[_], α) => F[α]]] = null
implicit def drosteSolveCofree[E]: Solve.Aux[Cofree[?[_], E], EnvT[E, ?[_], ?]] = null
implicit def drosteSolveCatsCofree[E]: Solve.Aux[cats.free.Cofree[?[_], E], EnvT[E, ?[_], ?]] = null
}
26 changes: 14 additions & 12 deletions modules/core/src/main/scala/qq/droste/data/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import cats.Functor
import cats.syntax.functor._
import meta.Meta

import data.prelude._

object `package` {

type Fix[F[_]] // = F[Fix[F]]
Expand Down Expand Up @@ -36,15 +38,15 @@ object `package` {

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

implicit final class CofreeOps[F[_], A](val cofree: Cofree[F, A]) extends AnyVal {
def tuple: (A, F[Cofree[F, A]]) = Cofree.uncofree(cofree)
def head: A = tuple._1
def tail: F[Cofree[F, A]] = tuple._2
final class Ops[F[_], A](val cofree: Cofree[F, A]) extends AnyVal {
def tuple: (A, F[Cofree[F, A]]) = Cofree.uncofree(cofree)
def head: A = tuple._1
def tail: F[Cofree[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 toCats(implicit ev: Functor[F]): cats.free.Cofree[F, A] =
cats.free.Cofree(head, Eval.later(tail.map(_.toCats)))
}
}

type EnvT[E, W[_], A] // = (E, W[A])
Expand All @@ -54,11 +56,11 @@ object `package` {
def apply [E, W[_], A](f: (E, W[A])): EnvT[E, W, A] = macro Meta.fastCast
def envT [E, W[_], A](f: (E, W[A])): EnvT[E, W, A] = macro Meta.fastCast
def unenvT[E, W[_], A](f: EnvT[E, W, A]): (E, W[A]) = macro Meta.fastCast
}

implicit class EnvTOps[E, W[_], A](val envT: EnvT[E, W, A]) extends AnyVal {
def tuple: (E, W[A]) = EnvT.unenvT(envT)
def ask: E = tuple._1
def lower: W[A] = tuple._2
final class Ops[E, W[_], A](val envT: EnvT[E, W, A]) extends AnyVal {
def tuple: (E, W[A]) = EnvT.unenvT(envT)
def ask: E = tuple._1
def lower: W[A] = tuple._2
}
}
}
15 changes: 14 additions & 1 deletion modules/core/src/main/scala/qq/droste/data/prelude.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,22 @@ import cats.Traverse
import cats.syntax.functor._
import cats.syntax.traverse._

import util.DefaultTraverse

package object prelude extends DataPrelude
import prelude._

private[droste] trait DataPrelude
extends DataInstances
with DataOps

private[droste] trait DataPrelude extends DataInstances
private[data] sealed trait DataOps {
implicit def toCofreeOps[F[_], A](cofree: Cofree[F, A]): Cofree.Ops[F, A] =
new Cofree.Ops[F, A](cofree)

implicit def toEnvTOps[E, W[_], A](envT: EnvT[E, W, A]): EnvT.Ops[E, W, A] =
new EnvT.Ops[E, W, A](envT)
}

private[data] sealed trait DataInstances extends DataInstances0 {
implicit def drosteEnvTTraverse[E, W[_]: Traverse]: Traverse[EnvT[E, W, ?]] =
Expand Down
1 change: 0 additions & 1 deletion modules/core/src/main/scala/qq/droste/package.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package qq.droste

import cats.Functor
import syntax._

object `package` {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package qq.droste
package util

import cats.Applicative
import cats.Eval
import cats.Monoid
import cats.Traverse
Expand All @@ -19,4 +19,4 @@ trait DefaultTraverse[F[_]] extends Traverse[F] {
def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
foldMap[A, Eval[B] => Eval[B]](fa)(a => lbb => Eval.defer(f(a, lbb)))(
Category[Function1].algebra)(lb)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import cats.implicits._

import qq.droste._
import qq.droste.data._
import qq.droste.util.DefaultTraverse

import scala.annotation.tailrec

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ import eu.timepit.refined.auto._
import eu.timepit.refined.numeric._
import eu.timepit.refined.scalacheck.numeric._

import data.Fix
import cats.Eval
import cats.instances.option._

import data.prelude._
import data.Cofree
import data.EnvT
import data.Fix
import data.Mu
import data.Nu

class SchemePartialBasisTests extends Properties("scheme.apply[???]") {
class SchemePartialBasisTests extends Properties("SchemePartialBasis") {

property("scheme[Fix].ana") = {

Expand All @@ -43,6 +44,17 @@ class SchemePartialBasisTests extends Properties("scheme.apply[???]") {
forAll((n: Int Refined Less[W.`100`.T]) => f(n) ?= expected(n))
}

property("scheme[cats.free.Cofree[?[_], Int]].ana") = {

val f = scheme[cats.free.Cofree[?[_], Int]].ana((n: Int) => EnvT(n, if (n > 0) Some(n - 1) else None))

def expected(n: Int): cats.free.Cofree[Option, Int] =
if (n > 0) cats.free.Cofree(n, Eval.now(Some(expected(n - 1))))
else cats.free.Cofree(n, Eval.now(None: Option[cats.free.Cofree[Option, Int]]))

forAll((n: Int Refined Less[W.`100`.T]) => f(n) ?= expected(n))
}

property("scheme[Mu].ana") = {

val f = scheme[Mu].ana((n: Int) => if (n > 0) Some(n - 1) else None)
Expand Down

0 comments on commit 1e5bebb

Please sign in to comment.