/core/src/main/scala/scalaz/Traverse.scala

http://github.com/scalaz/scalaz · Scala · 233 lines · 147 code · 47 blank · 39 comment · 4 complexity · 4a591e5e027939dcc06f0e6b1fb69c64 MD5 · raw file

  1. package scalaz
  2. ////
  3. import scalaz.Id.Id
  4. /**
  5. * Idiomatic traversal of a structure, as described in
  6. * [[http://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]].
  7. *
  8. * @see [[scalaz.Traverse.TraverseLaw]]
  9. */
  10. ////
  11. trait Traverse[F[_]] extends Functor[F] with Foldable[F] { self =>
  12. ////
  13. /** Transform `fa` using `f`, collecting all the `G`s with `ap`. */
  14. def traverseImpl[G[_]:Applicative,A,B](fa: F[A])(f: A => G[B]): G[F[B]]
  15. // derived functions
  16. /**The composition of Traverses `F` and `G`, `[x]F[G[x]]`, is a Traverse */
  17. def compose[G[_]](implicit G0: Traverse[G]): Traverse[λ[α => F[G[α]]]] =
  18. new CompositionTraverse[F, G] {
  19. implicit def F = self
  20. implicit def G = G0
  21. }
  22. /** The composition of Traverse `F` and Bitraverse `G`, `[x, y]F[G[x, y]]`, is a Bitraverse */
  23. def bicompose[G[_, _]: Bitraverse]: Bitraverse[λ[(α, β) => F[G[α, β]]]] =
  24. new CompositionTraverseBitraverse[F, G] {
  25. def F = self
  26. def G = implicitly
  27. }
  28. /**The product of Traverses `F` and `G`, `[x](F[x], G[x]])`, is a Traverse */
  29. def product[G[_]](implicit G0: Traverse[G]): Traverse[λ[α => (F[α], G[α])]] =
  30. new ProductTraverse[F, G] {
  31. implicit def F = self
  32. implicit def G = G0
  33. }
  34. /**The product of Traverse `F` and Traverse1 `G`, `[x](F[x], G[x]])`, is a Traverse1 */
  35. def product0[G[_]](implicit G0: Traverse1[G]): Traverse1[λ[α => (F[α], G[α])]] =
  36. new ProductTraverse1R[F, G] {
  37. def F = self
  38. def G = G0
  39. }
  40. class Traversal[G[_]](implicit G: Applicative[G]) {
  41. def run[A,B](fa: F[A])(f: A => G[B]): G[F[B]] = traverseImpl[G,A,B](fa)(f)
  42. }
  43. // reduce - given monoid
  44. def traversal[G[_]:Applicative]: Traversal[G] =
  45. new Traversal[G]
  46. def traversalS[S]: Traversal[State[S, *]] =
  47. new Traversal[State[S, *]]()(StateT.stateMonad) {
  48. override def run[A, B](fa: F[A])(f: A => State[S, B]) = traverseS(fa)(f)
  49. }
  50. def traverse[G[_]:Applicative,A,B](fa: F[A])(f: A => G[B]): G[F[B]] =
  51. traversal[G].run(fa)(f)
  52. /** A version of `traverse` that infers the type constructor `G`. */
  53. final def traverseU[A, GB](fa: F[A])(f: A => GB)(implicit G: Unapply[Applicative, GB]): G.M[F[G.A]] /*G[F[B]]*/ =
  54. G.TC.traverse(fa)(G.leibniz.onF(f))(this)
  55. /** A version of `traverse` where a subsequent monadic join is applied to the inner result. */
  56. final def traverseM[A, G[_], B](fa: F[A])(f: A => G[F[B]])(implicit G: Applicative[G], F: Bind[F]): G[F[B]] =
  57. G.map(G.traverse(fa)(f)(this))(F.join)
  58. /** Traverse with `State`. */
  59. def traverseS[S,A,B](fa: F[A])(f: A => State[S,B]): State[S,F[B]] =
  60. traverseSTrampoline[S, Id.Id, A, B](fa)(f)
  61. def runTraverseS[S,A,B](fa: F[A], s: S)(f: A => State[S,B]): (S, F[B]) =
  62. traverseS(fa)(f)(s)
  63. /** Traverse `fa` with a `State[S, G[B]]`, internally using a `Trampoline` to avoid stack overflow. */
  64. def traverseSTrampoline[S, G[_] : Applicative, A, B](fa: F[A])(f: A => State[S, G[B]]): State[S, G[F[B]]] = {
  65. import Free._
  66. implicit val A = StateT.stateTMonadState[S, Trampoline].compose(Applicative[G])
  67. State[S, G[F[B]]](s => {
  68. val st = traverse[λ[α => StateT[S, Trampoline, G[α]]], A, B](fa)(f(_: A).lift[Trampoline])
  69. st.run(s).run
  70. })
  71. }
  72. /** Traverse `fa` with a `Kleisli[G, S, B]`, internally using a `Trampoline` to avoid stack overflow. */
  73. def traverseKTrampoline[S, G[_] : Applicative, A, B](fa: F[A])(f: A => Kleisli[G, S, B]): Kleisli[G, S, F[B]] = {
  74. import Free._
  75. implicit val A = Kleisli.kleisliMonadReader[Trampoline, S].compose(Applicative[G])
  76. Kleisli[G, S, F[B]](s => {
  77. val kl = traverse[λ[α => Kleisli[Trampoline, S, G[α]]], A, B](fa)(z => Kleisli[Id, S, G[B]](i => f(z)(i)).lift[Trampoline]).run(s)
  78. kl.run
  79. })
  80. }
  81. /** Traverse with the identity function. */
  82. def sequence[G[_]:Applicative,A](fga: F[G[A]]): G[F[A]] =
  83. traversal[G].run[G[A], A](fga)(ga => ga)
  84. /** Traverse with `State`. */
  85. def sequenceS[S,A](fga: F[State[S,A]]): State[S,F[A]] =
  86. traverseS(fga)(x => x)
  87. /** A version of `sequence` that infers the nested type constructor. */
  88. final def sequenceU[A](self: F[A])(implicit G: Unapply[Applicative, A]): G.M[F[G.A]] /*G[F[A]] */ =
  89. G.TC.traverse(self)(x => G.apply(x))(this)
  90. /** A version of `sequence` where a subsequent monadic join is applied to the inner result */
  91. def sequenceM[A, G[_]](fgfa: F[G[F[A]]])(implicit G: Applicative[G], F: Bind[F]): G[F[A]] =
  92. G.map(sequence(fgfa))(F.join)
  93. override def map[A,B](fa: F[A])(f: A => B): F[B] =
  94. traversal[Id](Id.id).run(fa)(f)
  95. def foldLShape[A,B](fa: F[A], z: B)(f: (B,A) => B): (B, F[Unit]) =
  96. runTraverseS(fa, z)(a => State.modify(f(_, a)))
  97. override def foldLeft[A,B](fa: F[A], z: B)(f: (B,A) => B): B = foldLShape(fa, z)(f)._1
  98. def foldMap[A,B](fa: F[A])(f: A => B)(implicit F: Monoid[B]): B = foldLShape(fa, F.zero)((b, a) => F.append(b, f(a)))._1
  99. override def foldRight[A, B](fa: F[A], z: => B)(f: (A, => B) => B) =
  100. foldMap(fa)((a: A) => Endo.endoByName[B](f(a, _))) apply z
  101. def reverse[A](fa: F[A]): F[A] = {
  102. val (as, shape) = mapAccumL(fa, scala.List[A]())((t,h) => (h :: t,h))
  103. runTraverseS(shape, as)(_ => for {
  104. e <- State.get
  105. _ <- State.put(e.tail)
  106. } yield e.head)._2
  107. }
  108. def zipWith[A,B,C](fa: F[A], fb: F[B])(f: (A, Option[B]) => C): (List[B], F[C]) =
  109. runTraverseS(fa, toList(fb))(a => for {
  110. bs <- State.get
  111. _ <- State.put(if (bs.isEmpty) bs else bs.tail)
  112. } yield f(a, bs.headOption))
  113. def zipWithL[A,B,C](fa: F[A], fb: F[B])(f: (A,Option[B]) => C): F[C] = zipWith(fa, fb)(f)._2
  114. def zipWithR[A,B,C](fa: F[A], fb: F[B])(f: (Option[A],B) => C): F[C] = zipWith(fb, fa)((b,oa) => f(oa,b))._2
  115. def indexed[A](fa: F[A]): F[(Int, A)] = mapAccumL(fa, 0) { case (s, a) => (s + 1, (s, a)) }._2
  116. def zipL[A,B](fa: F[A], fb: F[B]): F[(A, Option[B])] = zipWithL(fa, fb)((_,_))
  117. def zipR[A,B](fa: F[A], fb: F[B]): F[(Option[A], B)] = zipWithR(fa, fb)((_,_))
  118. def mapAccumL[S,A,B](fa: F[A], z: S)(f: (S,A) => (S,B)): (S, F[B]) =
  119. runTraverseS(fa, z)(a => for {
  120. s1 <- State.init[S]
  121. (s2,b) = f(s1,a)
  122. _ <- State.put(s2)
  123. } yield b)
  124. def mapAccumR[S,A,B](fa: F[A], z: S)(f: (S,A) => (S,B)): (S, F[B]) =
  125. mapAccumL(reverse(fa), z)(f) match { case (s, fb) => (s, reverse(fb)) }
  126. trait TraverseLaw extends FunctorLaw {
  127. /** Traversal through the [[scalaz.Id]] effect is equivalent to `Functor#map` */
  128. def identityTraverse[A, B](fa: F[A], f: A => B)(implicit FB: Equal[F[B]]): Boolean = {
  129. FB.equal(traverse[Id, A, B](fa)(f), map(fa)(f))
  130. }
  131. /** Two sequentially dependent effects can be fused into one, their composition */
  132. def sequentialFusion[N[_], M[_], A, B, C](fa: F[A], amb: A => M[B], bnc: B => N[C])
  133. (implicit N: Applicative[N], M: Applicative[M], MN: Equal[M[N[F[C]]]]): Boolean = {
  134. type MN[A] = M[N[A]]
  135. val t1: MN[F[C]] = M.map(traverse[M, A, B](fa)(amb))(fb => traverse[N, B, C](fb)(bnc))
  136. val t2: MN[F[C]] = traverse[MN, A, C](fa)(a => M.map(amb(a))(bnc))(M compose N)
  137. MN.equal(t1, t2)
  138. }
  139. /** Traversal with the `point` function is the same as applying the `point` function directly */
  140. def purity[G[_], A](fa: F[A])(implicit G: Applicative[G], GFA: Equal[G[F[A]]]): Boolean =
  141. GFA.equal(traverse[G, A, A](fa)(G.point[A](_)), G.point(fa))
  142. /**
  143. * @param nat A natural transformation from `M` to `N` for which these properties hold:
  144. * `(a: A) => nat(Applicative[M].point[A](a)) === Applicative[N].point[A](a)`
  145. * `(f: M[A => B], ma: M[A]) => nat(Applicative[M].ap(ma)(f)) === Applicative[N].ap(nat(ma))(nat(f))`
  146. */
  147. def naturality[N[_], M[_], A](nat: (M ~> N))
  148. (fma: F[M[A]])
  149. (implicit N: Applicative[N], M: Applicative[M], NFA: Equal[N[F[A]]]): Boolean = {
  150. val n1: N[F[A]] = nat[F[A]](sequence[M, A](fma))
  151. val n2: N[F[A]] = sequence[N, A](map(fma)(ma => nat(ma)))
  152. NFA.equal(n1, n2)
  153. }
  154. /** Two independent effects can be fused into a single effect, their product. */
  155. def parallelFusion[N[_], M[_], A, B](fa: F[A], amb: A => M[B], anb: A => N[B])
  156. (implicit N: Applicative[N], M: Applicative[M], MN: Equal[(M[F[B]], N[F[B]])]): Boolean = {
  157. type MN[A] = (M[A], N[A])
  158. val t1: MN[F[B]] = (traverse[M, A, B](fa)(amb), traverse[N, A, B](fa)(anb))
  159. val t2: MN[F[B]] = traverse[MN, A, B](fa)(a => (amb(a), anb(a)))(M product N)
  160. MN.equal(t1, t2)
  161. }
  162. }
  163. def traverseLaw = new TraverseLaw {}
  164. ////
  165. val traverseSyntax: scalaz.syntax.TraverseSyntax[F] =
  166. new scalaz.syntax.TraverseSyntax[F] { def F = Traverse.this }
  167. }
  168. object Traverse {
  169. @inline def apply[F[_]](implicit F: Traverse[F]): Traverse[F] = F
  170. import Isomorphism._
  171. def fromIso[F[_], G[_]](D: F <~> G)(implicit E: Traverse[G]): Traverse[F] =
  172. new IsomorphismTraverse[F, G] {
  173. override def G: Traverse[G] = E
  174. override def iso: F <~> G = D
  175. }
  176. ////
  177. ////
  178. }
  179. trait IsomorphismTraverse[F[_], G[_]] extends Traverse[F] with IsomorphismFunctor[F, G] with IsomorphismFoldable[F, G]{
  180. implicit def G: Traverse[G]
  181. ////
  182. protected[this] override final def naturalTrans: F ~> G = iso.to
  183. override def traverseImpl[H[_] : Applicative, A, B](fa: F[A])(f: A => H[B]): H[F[B]] =
  184. Applicative[H].map(G.traverseImpl(iso.to(fa))(f))(iso.from.apply)
  185. ////
  186. }