Skip to content

Commit

Permalink
Added Free instance for Id (typelevel#2383)
Browse files Browse the repository at this point in the history
  • Loading branch information
barambani authored and catostrophe committed Sep 15, 2018
1 parent b5b8f8d commit 2e3a50e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 16 deletions.
37 changes: 22 additions & 15 deletions free/src/main/scala/cats/free/Free.scala
Original file line number Diff line number Diff line change
Expand Up @@ -292,21 +292,9 @@ object Free extends FreeInstances {
def match_[F[_], G[_], A](fa: Free[F, A])(implicit F: Functor[F], I: InjectK[G, F]): Option[G[Free[F, A]]] =
fa.resume.fold(I.prj(_), _ => None)

/**
* `Free[S, ?]` has a monad for any type constructor `S[_]`.
*/
implicit def catsFreeMonadForFree[S[_]]: Monad[Free[S, ?]] =
new Monad[Free[S, ?]] with StackSafeMonad[Free[S, ?]] {
def pure[A](a: A): Free[S, A] = Free.pure(a)
override def map[A, B](fa: Free[S, A])(f: A => B): Free[S, B] = fa.map(f)
def flatMap[A, B](a: Free[S, A])(f: A => Free[S, B]): Free[S, B] = a.flatMap(f)
}
implicit def catsFreeMonadForId: Monad[Free[Id, ?]] = catsFreeMonadForFree[Id]

implicit def catsFreeDeferForFree[S[_]]: Defer[Free[S, ?]] =
new Defer[Free[S, ?]] {
def defer[A](fa: => Free[S, A]): Free[S, A] =
Free.defer(fa)
}
implicit def catsFreeDeferForId: Defer[Free[Id, ?]] = catsFreeDeferForFree[Id]
}

private trait FreeFoldable[F[_]] extends Foldable[Free[F, ?]] {
Expand Down Expand Up @@ -343,7 +331,26 @@ private trait FreeTraverse[F[_]] extends Traverse[Free[F, ?]] with FreeFoldable[
override final def map[A, B](fa: Free[F, A])(f: A => B): Free[F, B] = fa.map(f)
}

sealed private[free] abstract class FreeInstances {
sealed private[free] abstract class FreeInstances extends FreeInstances1 {

/**
* `Free[S, ?]` has a monad for any type constructor `S[_]`.
*/
implicit def catsFreeMonadForFree[S[_]]: Monad[Free[S, ?]] =
new Monad[Free[S, ?]] with StackSafeMonad[Free[S, ?]] {
def pure[A](a: A): Free[S, A] = Free.pure(a)
override def map[A, B](fa: Free[S, A])(f: A => B): Free[S, B] = fa.map(f)
def flatMap[A, B](a: Free[S, A])(f: A => Free[S, B]): Free[S, B] = a.flatMap(f)
}

implicit def catsFreeDeferForFree[S[_]]: Defer[Free[S, ?]] =
new Defer[Free[S, ?]] {
def defer[A](fa: => Free[S, A]): Free[S, A] =
Free.defer(fa)
}
}

sealed private[free] abstract class FreeInstances1 {

implicit def catsFreeFoldableForFree[F[_]](
implicit
Expand Down
16 changes: 15 additions & 1 deletion free/src/test/scala/cats/free/FreeSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ class FreeSuite extends CatsSuite {

implicit val iso = SemigroupalTests.Isomorphisms.invariant[Free[Option, ?]]

Monad[Free[Id, ?]]
implicitly[Monad[Free[Id, ?]]]

checkAll("Free[Id, ?]", DeferTests[Free[Id, ?]].defer[Int])
checkAll("Free[Id, ?]", MonadTests[Free[Id, ?]].monad[Int, Int, Int])
checkAll("Monad[Free[Id, ?]]", SerializableTests.serializable(Monad[Free[Id, ?]]))

checkAll("Free[Option, ?]", DeferTests[Free[Option, ?]].defer[Int])
checkAll("Free[Option, ?]", MonadTests[Free[Option, ?]].monad[Int, Int, Int])
checkAll("Monad[Free[Option, ?]]", SerializableTests.serializable(Monad[Free[Option, ?]]))
Expand Down Expand Up @@ -224,7 +231,14 @@ object FreeSuite extends FreeSuiteInstances {
freeEq[Function0, A]
}

sealed trait FreeSuiteInstances {
sealed trait FreeSuiteInstances extends FreeSuiteInstances1 {

implicit def freeIdArbitrary[A](implicit A: Arbitrary[A]): Arbitrary[Free[Id, A]] = freeArbitrary[Id, A]

implicit def freeIdEq[A](implicit SA: Eq[A]): Eq[Free[Id, A]] = freeEq[Id, A]
}

sealed trait FreeSuiteInstances1 {
val headOptionU = λ[FunctionK[List,Option]](_.headOption)

private def freeGen[F[_], A](maxDepth: Int)(implicit F: Arbitrary[F[A]], A: Arbitrary[A]): Gen[Free[F, A]] = {
Expand Down

0 comments on commit 2e3a50e

Please sign in to comment.