/core/src/main/scala/scalaz/Free.scala

http://github.com/scalaz/scalaz · Scala · 530 lines · 360 code · 84 blank · 86 comment · 0 complexity · c80122a8595f25b3958a4b855414c66b MD5 · raw file

  1. package scalaz
  2. import annotation.tailrec
  3. import Free._
  4. // See explanation in comments on function1CovariantByName
  5. import std.function.{function1Covariant => _, function1CovariantByName, _}
  6. import std.tuple._
  7. object Free extends FreeInstances {
  8. /** Collapse a trampoline to a single step. */
  9. def reset[A](r: Trampoline[A]): Trampoline[A] = { val a = r.run; return_(a) }
  10. /** Suspend the given computation in a single step. */
  11. def return_[S[_], A](value: => A)(implicit S: Applicative[S]): Free[S, A] =
  12. liftF[S, A](S.point(value))
  13. /** Alias for `point` */
  14. def pure[S[_], A](value: A): Free[S, A] = point(value)
  15. /** Absorb a step into the free monad. */
  16. def roll[S[_], A](value: S[Free[S, A]]): Free[S, A] =
  17. liftF(value).flatMap(x => x)
  18. private[this] val pointUnitCache: Free[Id.Id, Unit] = point[Id.Id, Unit](())
  19. // Cache `point(())` to avoid frequent allocation
  20. @inline private def pointUnit[S[_]]: Free[S, Unit] = pointUnitCache.asInstanceOf[Free[S, Unit]]
  21. /** Suspend a computation in a pure step of the applicative functor `S` */
  22. def suspend[S[_], A](value: => Free[S, A]): Free[S, A] =
  23. pointUnit.flatMap(_ => value)
  24. /** A version of `liftF` that infers the nested type constructor. */
  25. def liftFU[MA](value: => MA)(implicit MA: Unapply[Functor, MA]): Free[MA.M, MA.A] =
  26. liftF(MA(value))
  27. /** Monadic join for the higher-order monad `Free` */
  28. def joinF[S[_], A](value: Free[Free[S, *], A]): Free[S, A] =
  29. value.flatMapSuspension(NaturalTransformation.refl[Free[S, *]])
  30. /** A trampoline step that doesn't do anything. */
  31. def pause: Trampoline[Unit] =
  32. return_(())
  33. /** A source that produces the given value. */
  34. def produce[A](a: A): Source[A, Unit] =
  35. liftF[(A, *), Unit]((a, ()))
  36. /** A sink that waits for a single value and returns it. */
  37. def await[A]: Sink[A, A] = liftF[(=> A) => *, A](a => a)
  38. /** Absorb a step in `S` into the free monad for `S` */
  39. def apply[S[_], A](s: S[Free[S, A]]): Free[S, A] =
  40. roll(s)
  41. /** Return from the computation with the given value. */
  42. private case class Return[S[_], A](a: A) extends Free[S, A]
  43. /** Suspend the computation with the given suspension. */
  44. private case class Suspend[S[_], A](a: S[A]) extends Free[S, A]
  45. /** Call a subroutine and continue with the given function. */
  46. private case class Gosub[S[_], A0, B](a0: Free[S, A0], f0: A0 => Free[S, B]) extends Free[S, B] {
  47. type A = A0
  48. def a: Free[S, A] = a0
  49. def f: A => Free[S, B] = f0
  50. }
  51. /** A computation that can be stepped through, suspended, and paused
  52. *
  53. * @template
  54. */
  55. type Trampoline[A] = Free[Function0, A]
  56. /** A computation that produces values of type `A`, eventually resulting in a value of type `B`.
  57. *
  58. * @template
  59. */
  60. type Source[A, B] = Free[(A, *), B]
  61. /** A computation that accepts values of type `A`, eventually resulting in a value of type `B`.
  62. * Note the similarity to an [[scalaz.iteratee.Iteratee]].
  63. *
  64. * @template
  65. */
  66. type Sink[A, B] = Free[(=> A) => *, B]
  67. /** Suspends a value within a functor in a single step. Monadic unit for a higher-order monad. */
  68. def liftF[S[_], A](value: S[A]): Free[S, A] =
  69. Suspend(value)
  70. /** Return the given value in the free monad. */
  71. def point[S[_], A](value: A): Free[S, A] = Return[S, A](value)
  72. }
  73. /**
  74. * A free monad for a type constructor `S`.
  75. * Binding is done using the heap instead of the stack, allowing tail-call elimination.
  76. */
  77. sealed abstract class Free[S[_], A] {
  78. final def map[B](f: A => B): Free[S, B] =
  79. flatMap(a => Return(f(a)))
  80. /** Alias for `flatMap` */
  81. final def >>=[B](f: A => Free[S, B]): Free[S, B] = this flatMap f
  82. /** Binds the given continuation to the result of this computation. */
  83. final def flatMap[B](f: A => Free[S, B]): Free[S, B] = Gosub(this, f)
  84. /** Catamorphism. Run the first given function if Return, otherwise, the second given function. */
  85. final def fold[B](r: A => B, s: S[Free[S, A]] => B)(implicit S: Functor[S]): B =
  86. resume.fold(s, r)
  87. /** Evaluates a single layer of the free monad **/
  88. final def resume(implicit S: Functor[S]): (S[Free[S,A]] \/ A) =
  89. resumeC.leftMap(_.run)
  90. /** Evaluates a single layer of the free monad **/
  91. @tailrec final def resumeC: (Coyoneda[S, Free[S,A]] \/ A) =
  92. this match {
  93. case Return(a) => \/-(a)
  94. case Suspend(t) => -\/(Coyoneda(t)(Return(_)))
  95. case b @ Gosub(_, _) => b.a match {
  96. case Return(a) => b.f(a).resumeC
  97. case Suspend(t) => -\/(Coyoneda(t)(b.f))
  98. case c @ Gosub(_, _) => c.a.flatMap(z => c.f(z).flatMap(b.f)).resumeC
  99. }
  100. }
  101. /** Changes the suspension functor by the given natural transformation. */
  102. final def mapSuspension[T[_]](f: S ~> T): Free[T, A] =
  103. flatMapSuspension(λ[S ~> Free[T,*]](s => Suspend(f(s))))
  104. /** Modifies the first suspension with the given natural transformation. */
  105. final def mapFirstSuspension(f: S ~> S): Free[S, A] =
  106. step match {
  107. case Suspend(s) => Suspend(f(s))
  108. case a@Gosub(_, _) => a.a match {
  109. case Suspend(s) => Suspend(f(s)).flatMap(a.f)
  110. case _ => a.a.mapFirstSuspension(f).flatMap(a.f)
  111. }
  112. case x => x
  113. }
  114. /**
  115. * Substitutes a free monad over the given functor into the suspension functor of this program.
  116. * `Free` is a monad in an endofunctor category and this is its monadic bind.
  117. */
  118. final def flatMapSuspension[T[_]](f: S ~> Free[T, *]): Free[T, A] =
  119. foldMap[Free[T,*]](f)(freeMonad[T])
  120. /** Applies a function `f` to a value in this monad and a corresponding value in the dual comonad, annihilating both. */
  121. final def zapWith[G[_], B, C](bs: Cofree[G, B])(f: (A, B) => C)(implicit d: Zap[S, G]): C =
  122. Zap.monadComonadZap.zapWith(this, bs)(f)
  123. /** Applies a function in a comonad to the corresponding value in this monad, annihilating both. */
  124. final def zap[G[_], B](fs: Cofree[G, A => B])(implicit d: Zap[S, G]): B =
  125. zapWith(fs)((a, f) => f(a))
  126. /** Runs a single step, using a function that extracts the resumption from its suspension functor. */
  127. final def bounce(f: S[Free[S, A]] => Free[S, A])(implicit S: Functor[S]): Free[S, A] = resume match {
  128. case -\/(s) => f(s)
  129. case \/-(r) => Return(r)
  130. }
  131. /** Runs to completion, using a function that extracts the resumption from its suspension functor. */
  132. final def go(f: S[Free[S, A]] => Free[S, A])(implicit S: Functor[S]): A = {
  133. @tailrec def go2(t: Free[S, A]): A = t.resume match {
  134. case -\/(s) => go2(f(s))
  135. case \/-(r) => r
  136. }
  137. go2(this)
  138. }
  139. /**
  140. * Runs to completion, using a function that maps the resumption from `S` to a monad `M`.
  141. * @since 7.0.1
  142. */
  143. final def runM[M[_]](f: S[Free[S, A]] => M[Free[S, A]])(implicit S: Functor[S], M: Monad[M]): M[A] = {
  144. def runM2(t: Free[S, A]): M[A] = t.resume match {
  145. case -\/(s) => Monad[M].bind(f(s))(runM2)
  146. case \/-(r) => Monad[M].pure(r)
  147. }
  148. runM2(this)
  149. }
  150. /**
  151. * Run Free using constant stack.
  152. */
  153. final def runRecM[M[_]](f: S[Free[S, A]] => M[Free[S, A]])(implicit S: Functor[S], M: Applicative[M], B: BindRec[M]): M[A] = {
  154. B.tailrecM(this)(_.resume match {
  155. case -\/(sf) => M.map(f(sf))(\/.left)
  156. case a @ \/-(_) => M.point(a.coerceLeft)
  157. })
  158. }
  159. /**
  160. * Evaluate one layer in the free monad, re-associating any left-nested binds to the right
  161. * and pulling the first suspension to the top.
  162. */
  163. @tailrec final def step: Free[S, A] = this match {
  164. case x@Gosub(_, _) => x.a match {
  165. case b@Gosub(_, _) =>
  166. b.a.flatMap(a => b.f(a).flatMap(x.f)).step
  167. case Return(b)=>
  168. x.f(b).step
  169. case _ =>
  170. x
  171. }
  172. case x => x
  173. }
  174. /**
  175. * Re-associate any left-nested binds to the right, pull the first suspension to the top
  176. * and then pass the result to one of the callbacks.
  177. */
  178. @tailrec private[scalaz] final def foldStep[B](
  179. onReturn: A => B,
  180. onSuspend: S[A] => B,
  181. onGosub: ((S[X], X => Free[S, A]) forSome { type X }) => B
  182. ): B = this match {
  183. case Gosub(fz, f) => fz match {
  184. case Gosub(fy, g) => fy.flatMap(y => g(y).flatMap(f)).foldStep(onReturn, onSuspend, onGosub)
  185. case Suspend(sz) => onGosub((sz, f))
  186. case Return(z) => f(z).foldStep(onReturn, onSuspend, onGosub)
  187. }
  188. case Suspend(sa) => onSuspend(sa)
  189. case Return(a) => onReturn(a)
  190. }
  191. /**
  192. * Catamorphism for `Free`.
  193. * Runs to completion, mapping the suspension with the given transformation at each step and
  194. * accumulating into the monad `M`.
  195. */
  196. final def foldMap[M[_]](f: S ~> M)(implicit M: Monad[M]): M[A] =
  197. step match {
  198. case Return(a) => M.pure(a)
  199. case Suspend(s) => f(s)
  200. // This is stack safe because `step` ensures right-associativity of Gosub
  201. case a@Gosub(_, _) => M.bind(a.a foldMap f)(c => a.f(c) foldMap f)
  202. }
  203. final def foldMapRec[M[_]](f: S ~> M)(implicit M: Applicative[M], B: BindRec[M]): M[A] =
  204. B.tailrecM(this){
  205. _.step match {
  206. case Return(a) => M.point(\/-(a))
  207. case Suspend(t) => M.map(f(t))(\/.right)
  208. case b @ Gosub(_, _) => (b.a: @unchecked) match {
  209. case Suspend(t) => M.map(f(t))(a => -\/(b.f(a)))
  210. }
  211. }
  212. }
  213. import Id._
  214. /**
  215. * Folds this free recursion to the right using the given natural transformations.
  216. */
  217. final def foldRight[G[_]](z: Id ~> G)(f: λ[α => S[G[α]]] ~> G)(implicit S: Functor[S]): G[A] =
  218. this.resume match {
  219. case -\/(s) => f(S.map(s)(_.foldRight(z)(f)))
  220. case \/-(r) => z(r)
  221. }
  222. /** Runs to completion, allowing the resumption function to thread an arbitrary state of type `B`. */
  223. @tailrec final def foldRun[B](b: B)(f: λ[α => (B, S[α])] ~> (B, *)): (B, A) =
  224. step match {
  225. case Return(a) => (b, a)
  226. case Suspend(sa) => f((b, sa))
  227. case g @ Gosub(_, _) => g.a match {
  228. case Suspend(sz) =>
  229. val (b1, z) = f((b, sz))
  230. g.f(z).foldRun(b1)(f)
  231. case _ => sys.error("Unreachable code: `Gosub` returned from `step` must have `Suspend` on the left")
  232. }
  233. }
  234. /** Variant of `foldRun` that allows to interleave effect `M` at each step. */
  235. final def foldRunM[M[_], B](b: B)(f: λ[α => (B, S[α])] ~> λ[α => M[(B, α)]])(implicit M0: Applicative[M], M1: BindRec[M]): M[(B, A)] =
  236. M1.tailrecM((b, this)) { case (b, fa) =>
  237. fa.step match {
  238. case Return(a) => M0.point(\/-((b, a)))
  239. case Suspend(sa) => M0.map(f((b, sa)))(\/.right)
  240. case g @ Gosub(_, _) => g.a match {
  241. case Suspend(sz) =>
  242. M0.map(f((b, sz))) { case (b, z) => -\/((b, g.f(z))) }
  243. case _ => sys.error("Unreachable code: `Gosub` returned from `step` must have `Suspend` on the left")
  244. }
  245. }
  246. }
  247. /** Runs a trampoline all the way to the end, tail-recursively. */
  248. final def run(implicit ev: Free[S, A] === Trampoline[A]): A =
  249. ev(this).go(_())
  250. /** Interleave this computation with another, combining the results with the given function. */
  251. final def zipWith[B, C](tb: Free[S, B])(f: (A, B) => C): Free[S, C] = {
  252. (step, tb.step) match {
  253. case (Return(a), Return(b)) => Return(f(a, b))
  254. case (a@Suspend(_), Return(b)) => a.flatMap(x => Return(f(x, b)))
  255. case (Return(a), b@Suspend(_)) => b.flatMap(x => Return(f(a, x)))
  256. case (a@Suspend(_), b@Suspend(_)) => a.flatMap(x => b.map(y => f(x, y)))
  257. case (a@Gosub(_, _), Return(b)) => a.a.flatMap(x => a.f(x).map(f(_, b)))
  258. case (a@Gosub(_, _), b@Suspend(_)) => a.a.flatMap(x => b.flatMap(y => a.f(x).map(f(_, y))))
  259. case (a@Gosub(_, _), b@Gosub(_, _)) => a.a.zipWith(b.a)((x, y) => a.f(x).zipWith(b.f(y))(f)).flatMap(x => x)
  260. case (a, b@Gosub(_, _)) => a.flatMap(x => b.a.flatMap(y => b.f(y).map(f(x, _))))
  261. }
  262. }
  263. /** Runs a `Source` all the way to the end, tail-recursively, collecting the produced values. */
  264. def collect[B](implicit ev: Free[S, A] === Source[B, A]): (Vector[B], A) = {
  265. @tailrec def go(c: Source[B, A], v: Vector[B] = Vector()): (Vector[B], A) =
  266. c.resume match {
  267. case -\/((b, cont)) => go(cont, v :+ b)
  268. case \/-(r) => (v, r)
  269. }
  270. go(ev(this))
  271. }
  272. /** Drive this `Source` with the given Sink. */
  273. def drive[E, B](sink: Sink[Option[E], B])(implicit ev: Free[S, A] === Source[E, A]): (A, B) = {
  274. @tailrec def go(src: Source[E, A], snk: Sink[Option[E], B]): (A, B) =
  275. (src.resume, snk.resume) match {
  276. case (-\/((e, c)), -\/(f)) => go(c, f(Some(e)))
  277. case (-\/((e, c)), \/-(y)) => go(c, Monad[Sink[Option[E], *]].pure(y))
  278. case (\/-(x), -\/(f)) => go(Monad[Source[E, *]].pure(x), f(None))
  279. case (\/-(x), \/-(y)) => (x, y)
  280. }
  281. go(ev(this), sink)
  282. }
  283. /** Feed the given stream to this `Source`. */
  284. def feed[E](ss: Stream[E])(implicit ev: Free[S, A] === Sink[E, A]): A = {
  285. @tailrec def go(snk: Sink[E, A], rest: Stream[E]): A = (rest, snk.resume) match {
  286. case (x #:: xs, -\/(f)) => go(f(x), xs)
  287. case (Stream(), -\/(f)) => go(f(sys.error("No more values.")), Stream())
  288. case (_, \/-(r)) => r
  289. }
  290. go(ev(this), ss)
  291. }
  292. /** Feed the given source to this `Sink`. */
  293. def drain[E, B](source: Source[E, B])(implicit ev: Free[S, A] === Sink[E, A]): (A, B) = {
  294. @tailrec def go(src: Source[E, B], snk: Sink[E, A]): (A, B) = (src.resume, snk.resume) match {
  295. case (-\/((e, c)), -\/(f)) => go(c, f(e))
  296. case (-\/((e, c)), \/-(y)) => go(c, Monad[Sink[E, *]].pure(y))
  297. case (\/-(x), -\/(f)) => sys.error("Not enough values in source.")
  298. case (\/-(x), \/-(y)) => (y, x)
  299. }
  300. go(source, ev(this))
  301. }
  302. /** Duplication in `Free` as a comonad in the endofunctor category. */
  303. def duplicateF: Free[Free[S, *], A] = extendF[Free[S,*]](NaturalTransformation.refl[Free[S,*]])
  304. /** Extension in `Free` as a comonad in the endofunctor category. */
  305. def extendF[T[_]](f: Free[S, *] ~> T): Free[T, A] = mapSuspension(λ[S ~> T](x => f(liftF(x))))
  306. /** Extraction from `Free` as a comonad in the endofunctor category. */
  307. def extractF(implicit S: Monad[S]): S[A] = foldMap(NaturalTransformation.refl[S])
  308. def toFreeT: FreeT[S, Id, A] =
  309. this match {
  310. case Return(a) =>
  311. FreeT.point(a)
  312. case Suspend(a) =>
  313. FreeT.liftF(a)
  314. case a @ Gosub(_, _) =>
  315. a.a.toFreeT.flatMap(a.f.andThen(_.toFreeT))
  316. }
  317. }
  318. object Trampoline {
  319. def done[A](a: A): Trampoline[A] =
  320. Free.pure[Function0,A](a)
  321. def delay[A](a: => A): Trampoline[A] =
  322. suspend(done(a))
  323. def suspend[A](a: => Trampoline[A]): Trampoline[A] =
  324. Free.suspend(a)
  325. }
  326. sealed abstract class FreeInstances4 {
  327. implicit val trampolineInstance: Comonad[Trampoline] =
  328. new Comonad[Trampoline] {
  329. override def map[A, B](fa: Trampoline[A])(f: A => B) = fa map f
  330. def copoint[A](fa: Trampoline[A]) = fa.run
  331. def cobind[A, B](fa: Trampoline[A])(f: Trampoline[A] => B) = return_(f(fa))
  332. override def cojoin[A](fa: Trampoline[A]) = Free.point(fa)
  333. }
  334. }
  335. sealed abstract class FreeInstances3 extends FreeInstances4 {
  336. implicit def freeFoldable[F[_]: Foldable]: Foldable[Free[F, *]] =
  337. new FreeFoldable[F] {
  338. def F = implicitly
  339. }
  340. }
  341. sealed abstract class FreeInstances2 extends FreeInstances3 {
  342. implicit def freeFoldable1[F[_]: Foldable1]: Foldable1[Free[F, *]] =
  343. new FreeFoldable1[F] {
  344. def F = implicitly
  345. }
  346. }
  347. sealed abstract class FreeInstances1 extends FreeInstances2 {
  348. implicit def freeTraverse[F[_]: Traverse]: Traverse[Free[F, *]] =
  349. new FreeTraverse[F] {
  350. def F = implicitly
  351. }
  352. }
  353. sealed abstract class FreeInstances0 extends FreeInstances1 {
  354. implicit def freeTraverse1[F[_]: Traverse1]: Traverse1[Free[F, *]] =
  355. new FreeTraverse1[F] {
  356. def F = implicitly
  357. }
  358. implicit def freeSemigroup[S[_], A: Semigroup]: Semigroup[Free[S, A]] =
  359. Semigroup.liftSemigroup[Free[S, *], A]
  360. }
  361. sealed abstract class FreeInstances extends FreeInstances0 {
  362. implicit def freeMonad[S[_]]: Monad[Free[S, *]] with BindRec[Free[S, *]] =
  363. new Monad[Free[S, *]] with BindRec[Free[S, *]] {
  364. override def map[A, B](fa: Free[S, A])(f: A => B) = fa map f
  365. def bind[A, B](a: Free[S, A])(f: A => Free[S, B]) = a flatMap f
  366. def point[A](a: => A) = Free.point(a)
  367. // Free trampolines, should be alright to just perform binds.
  368. def tailrecM[A, B](a: A)(f: A => Free[S, A \/ B]): Free[S, B] =
  369. f(a).flatMap(_.fold(tailrecM(_)(f), point(_)))
  370. }
  371. implicit def freeZip[S[_]](implicit Z: Zip[S]): Zip[Free[S, *]] =
  372. new Zip[Free[S, *]] {
  373. override def zip[A, B](aa: => Free[S, A], bb: => Free[S, B]) =
  374. (aa.resumeC, bb.resumeC) match {
  375. case (-\/(a), -\/(b)) => liftF(Z.zip(a.fi, b.fi)).flatMap(ab => zip(a.k(ab._1), b.k(ab._2)))
  376. case (-\/(a), \/-(b)) => liftF(a.fi).flatMap(i => a.k(i).map((_, b)))
  377. case (\/-(a), -\/(b)) => liftF(b.fi).flatMap(i => b.k(i).map((a, _)))
  378. case (\/-(a), \/-(b)) => point((a, b))
  379. }
  380. }
  381. implicit def freeMonoid[S[_], A: Monoid]: Monoid[Free[S, A]] =
  382. Monoid.liftMonoid[Free[S, *], A]
  383. }
  384. private sealed trait FreeBind[F[_]] extends Bind[Free[F, *]] {
  385. override def map[A, B](fa: Free[F, A])(f: A => B) = fa map f
  386. def bind[A, B](a: Free[F, A])(f: A => Free[F, B]) = a flatMap f
  387. }
  388. private sealed trait FreeFoldable[F[_]] extends Foldable[Free[F, *]] {
  389. def F: Foldable[F]
  390. override final def foldMap[A, B: Monoid](fa: Free[F, A])(f: A => B): B =
  391. fa.foldStep(
  392. f,
  393. fa => F.foldMap(fa)(f),
  394. { case (fx, g) => F.foldMap(fx)(x => foldMap(g(x))(f)) }
  395. )
  396. override final def foldLeft[A, B](fa: Free[F, A], z: B)(f: (B, A) => B): B =
  397. fa.foldStep(
  398. a => f(z, a),
  399. fa => F.foldLeft(fa, z)(f),
  400. { case (fx, g) => F.foldLeft(fx, z)((b, x) => foldLeft(g(x), b)(f)) }
  401. )
  402. override final def foldRight[A, B](fa: Free[F, A], z: => B)(f: (A, => B) => B): B =
  403. fa.foldStep(
  404. a => f(a, z),
  405. fa => F.foldRight(fa, z)(f),
  406. { case (fx, g) => F.foldRight(fx, z)((x, b) => foldRight(g(x), b)(f)) }
  407. )
  408. }
  409. private sealed trait FreeFoldable1[F[_]] extends Foldable1[Free[F, *]] {
  410. def F: Foldable1[F]
  411. override final def foldMap1[A, B: Semigroup](fa: Free[F, A])(f: A => B): B =
  412. fa.foldStep(
  413. f,
  414. fa => F.foldMap1(fa)(f),
  415. { case (fx, g) => F.foldMap1(fx)(x => foldMap1(g(x))(f)) }
  416. )
  417. override final def foldMapRight1[A, B](fa: Free[F, A])(z: A => B)(f: (A, => B) => B): B =
  418. fa.foldStep(
  419. z,
  420. fa => F.foldMapRight1(fa)(z)(f),
  421. { case (fx, g) => F.foldMapRight1(fx)(x => foldMapRight1(g(x))(z)(f))((x, b) => foldRight(g(x), b)(f)) }
  422. )
  423. override final def foldMapLeft1[A, B](fa: Free[F, A])(z: A => B)(f: (B, A) => B): B =
  424. fa.foldStep(
  425. z,
  426. fa => F.foldMapLeft1(fa)(z)(f),
  427. { case (fx, g) => F.foldMapLeft1(fx)(x => foldMapLeft1(g(x))(z)(f))((b, x) => foldLeft(g(x), b)(f)) }
  428. )
  429. }
  430. private sealed trait FreeTraverse[F[_]] extends Traverse[Free[F, *]] with FreeFoldable[F]{
  431. implicit def F: Traverse[F]
  432. override final def map[A, B](fa: Free[F, A])(f: A => B) = fa map f
  433. override final def traverseImpl[G[_], A, B](fa: Free[F, A])(f: A => G[B])(implicit G: Applicative[G]): G[Free[F, B]] =
  434. fa.resume match {
  435. case -\/(s) => G.map(F.traverseImpl(s)(traverseImpl[G, A, B](_)(f)))(roll)
  436. case \/-(r) => G.map(f(r))(point)
  437. }
  438. }
  439. private sealed abstract class FreeTraverse1[F[_]] extends Traverse1[Free[F, *]] with FreeTraverse[F] with FreeFoldable1[F]{
  440. implicit def F: Traverse1[F]
  441. override final def traverse1Impl[G[_], A, B](fa: Free[F, A])(f: A => G[B])(implicit G: Apply[G]): G[Free[F, B]] =
  442. fa.resume match {
  443. case -\/(s) => G.map(F.traverse1Impl(s)(traverse1Impl[G, A, B](_)(f)))(roll)
  444. case \/-(r) => G.map(f(r))(point)
  445. }
  446. }