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