Skip to content

Commit

Permalink
Merge pull request #613 from ceedubs/hide-free-constructors
Browse files Browse the repository at this point in the history
Make Free/FreeApplicative constructors private
  • Loading branch information
adelbertc committed Nov 9, 2015
2 parents f20f021 + bc06262 commit a38fdb2
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 23 deletions.
8 changes: 4 additions & 4 deletions free/src/main/scala/cats/free/Free.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ object Free {
/**
* Return from the computation with the given value.
*/
final case class Pure[S[_], A](a: A) extends Free[S, A]
private final case class Pure[S[_], A](a: A) extends Free[S, A]

/** Suspend the computation with the given suspension. */
final case class Suspend[S[_], A](a: S[A]) extends Free[S, A]
private final case class Suspend[S[_], A](a: S[A]) extends Free[S, A]

/** Call a subroutine and continue with the given function. */
final case class Gosub[S[_], B, C](c: Free[S, C], f: C => Free[S, B]) extends Free[S, B]
private final case class Gosub[S[_], B, C](c: Free[S, C], f: C => Free[S, B]) extends Free[S, B]

/**
* Suspend a value within a functor lifting it to a Free.
Expand Down Expand Up @@ -95,7 +95,7 @@ sealed abstract class Free[S[_], A] extends Product with Serializable {
loop(this)
}

def run(implicit S: Comonad[S]): A = go(S.extract)
final def run(implicit S: Comonad[S]): A = go(S.extract)

/**
* Run to completion, using a function that maps the resumption
Expand Down
25 changes: 8 additions & 17 deletions free/src/main/scala/cats/free/FreeApplicative.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable
b match {
case Pure(f) =>
this.map(f)
case x@Ap() =>
apply(x.pivot)(self.ap(x.fn.map(fx => a => p => fx(p)(a))))
case Ap(pivot, fn) =>
apply(pivot)(self.ap(fn.map(fx => a => p => fx(p)(a))))
}

final def map[B](f: A => B): FA[F, B] =
this match {
case Pure(a) => Pure(f(a))
case x@Ap() => apply(x.pivot)(x.fn.map(f compose _))
case Ap(pivot, fn) => apply(pivot)(fn.map(f compose _))
}

/** Interprets/Runs the sequence of operations using the semantics of Applicative G
Expand All @@ -30,7 +30,7 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable
final def foldMap[G[_]](f: F ~> G)(implicit G: Applicative[G]): G[A] =
this match {
case Pure(a) => G.pure(a)
case x@Ap() => G.ap(f(x.pivot))(x.fn.foldMap(f))
case Ap(pivot, fn) => G.ap(f(pivot))(fn.foldMap(f))
}

/** Interpret/run the operations using the semantics of `Applicative[F]`.
Expand All @@ -48,7 +48,7 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable
}

/** Interpret this algebra into a Monoid */
def analyze[M:Monoid](f: F ~> λ[α => M]): M =
final def analyze[M:Monoid](f: F ~> λ[α => M]): M =
foldMap[Const[M, ?]](new (F ~> Const[M, ?]) {
def apply[X](x: F[X]): Const[M,X] = Const(f(x))
}).getConst
Expand All @@ -65,23 +65,14 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable
object FreeApplicative {
type FA[F[_], A] = FreeApplicative[F, A]

final case class Pure[F[_], A](a: A) extends FA[F, A]
private final case class Pure[F[_], A](a: A) extends FA[F, A]

abstract case class Ap[F[_], A]() extends FA[F, A] {
type Pivot
val pivot: F[Pivot]
val fn: FA[F, Pivot => A]
}
private final case class Ap[F[_], P, A](pivot: F[P], fn: FA[F, P => A]) extends FA[F, A]

final def pure[F[_], A](a: A): FA[F, A] =
Pure(a)

final def ap[F[_], P, A](fp: F[P])(f: FA[F, P => A]): FA[F, A] =
new Ap[F, A] {
type Pivot = P
val pivot: F[Pivot] = fp
val fn: FA[F, Pivot => A] = f
}
final def ap[F[_], P, A](fp: F[P])(f: FA[F, P => A]): FA[F, A] = Ap(fp, f)

final def lift[F[_], A](fa: F[A]): FA[F, A] =
ap(fa)(Pure(a => a))
Expand Down
4 changes: 2 additions & 2 deletions free/src/main/scala/cats/free/Trampoline.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import cats.std.function.function0Instance

// To workaround SI-7139 `object Trampoline` needs to be defined inside the package object
// together with the type alias.
abstract class TrampolineFunctions {
private[free] abstract class TrampolineFunctions {
def done[A](a: A): Trampoline[A] =
Free.Pure[Function0,A](a)
Free.pure[Function0, A](a)

def suspend[A](a: => Trampoline[A]): Trampoline[A] =
Free.suspend(a)
Expand Down

0 comments on commit a38fdb2

Please sign in to comment.