/core/src/main/scala/scalaz/StreamT.scala

http://github.com/scalaz/scalaz · Scala · 371 lines · 266 code · 73 blank · 32 comment · 12 complexity · 5cd376029e46cfec4eb2b73f22a2142c MD5 · raw file

  1. package scalaz
  2. import Id._
  3. /**
  4. * StreamT monad transformer.
  5. */
  6. sealed class StreamT[M[_], A](val step: M[StreamT.Step[A, StreamT[M, A]]]) {
  7. import StreamT._
  8. def uncons(implicit M: Monad[M]): M[Option[(A, StreamT[M, A])]] =
  9. M.bind(step) {
  10. case Yield(a, s) => M.point(Some((a, s())))
  11. case Skip(s) => s().uncons
  12. case Done() => M.point(None)
  13. }
  14. def unconsRec(implicit M: BindRec[M]): M[Option[(A, StreamT[M, A])]] =
  15. M.tailrecM(this)(s =>
  16. M.map(s.step) {
  17. case Yield(a, s1) => \/-(Some((a, s1())))
  18. case Skip(s1) => -\/(s1())
  19. case Done() => \/-(None)
  20. })
  21. def ::(a: A)(implicit M: Applicative[M]): StreamT[M, A] = StreamT[M, A](M.point(Yield(a, this)))
  22. def isEmpty(implicit M: Monad[M]): M[Boolean] = M.map(uncons)(_.isEmpty)
  23. def isEmptyRec(implicit M: BindRec[M]): M[Boolean] = M.map(unconsRec)(_.isEmpty)
  24. def head(implicit M: Monad[M]): M[A] = M.map(uncons)(_.getOrElse(sys.error("head: empty StreamT"))._1)
  25. def headRec(implicit M: BindRec[M]): M[A] = M.map(unconsRec)(_.getOrElse(sys.error("head: empty StreamT"))._1)
  26. def headOption(implicit M: Monad[M]): M[Option[A]] = M.map(uncons)(_.map(_._1))
  27. def headOptionRec(implicit M: BindRec[M]): M[Option[A]] = M.map(unconsRec)(_.map(_._1))
  28. def tailM(implicit M: Monad[M]): M[StreamT[M, A]] = M.map(uncons)(_.getOrElse(sys.error("tailM: empty StreamT"))._2)
  29. def tailMRec(implicit M: BindRec[M]): M[StreamT[M, A]] = M.map(unconsRec)(_.getOrElse(sys.error("tailM: empty StreamT"))._2)
  30. def tailOption(implicit M: Monad[M]): M[Option[StreamT[M, A]]] =
  31. M.map(uncons)(_.map(_._2))
  32. def tailOptionRec(implicit M: BindRec[M]): M[Option[StreamT[M, A]]] =
  33. M.map(unconsRec)(_.map(_._2))
  34. def trans[N[_]](t: M ~> N)(implicit M: Functor[M], N: Functor[N]): StreamT[N, A] =
  35. StreamT(t(M.map[Step[A, StreamT[M, A]], Step[A, StreamT[N, A]]](this.step) {
  36. case Yield(a, s) => Yield(a, s() trans t)
  37. case Skip(s) => Skip(s() trans t)
  38. case Done() => Done()
  39. }))
  40. def filter(p: A => Boolean)(implicit m: Functor[M]): StreamT[M, A] = stepMap[A] {
  41. case Yield(a, s) => if (p(a)) Yield(a, s() filter p) else Skip(s() filter p)
  42. case Skip(s) => Skip(s() filter p)
  43. case Done() => Done()
  44. }
  45. def drop(n: Int)(implicit M: Functor[M]): StreamT[M, A] = stepMap[A] {
  46. case Yield(a, s) => if (n > 0) Skip(s() drop (n - 1)) else Yield(a, s)
  47. case Skip(s) => Skip(s() drop n)
  48. case Done() => Done()
  49. }
  50. def dropWhile(p: A => Boolean)(implicit m: Functor[M]): StreamT[M, A] = stepMap[A] {
  51. case Yield(a, s) => if (p(a)) Skip(s() dropWhile p) else Yield(a, s)
  52. case Skip(s) => Skip(s() dropWhile p)
  53. case Done() => Done()
  54. }
  55. def take(n: Int)(implicit M: Functor[M]): StreamT[M, A] = stepMap[A] {
  56. case Yield(a, s) => if (n <= 0) Done() else Yield(a, s() take (n - 1))
  57. case Skip(s) => Skip(s() take n)
  58. case Done() => Done()
  59. }
  60. def takeWhile(p: A => Boolean)(implicit m: Functor[M]): StreamT[M, A] = stepMap[A] {
  61. case Yield(a, s) => if (p(a)) Yield(a, s() takeWhile p) else Done()
  62. case Skip(s) => Skip(s() takeWhile p)
  63. case Done() => Done()
  64. }
  65. def ++(bs: => StreamT[M, A])(implicit m: Functor[M]): StreamT[M, A] = stepMap[A] {
  66. case Yield(a, s) => Yield(a, s() ++ bs)
  67. case Skip(s) => Skip(s() ++ bs)
  68. case Done() => Skip(bs)
  69. }
  70. def flatMap[B](f: A => StreamT[M, B])(implicit m: Functor[M]): StreamT[M, B] = stepMap[B] {
  71. case Yield(a, s) => Skip(f(a) ++ (s() flatMap f))
  72. case Skip(s) => Skip(s() flatMap f)
  73. case Done() => Done()
  74. }
  75. def map[B](f: A => B)(implicit m: Functor[M]): StreamT[M, B] = stepMap[B] {
  76. case Yield(a, s) => Yield(f(a), s() map f)
  77. case Skip(s) => Skip(s() map f)
  78. case Done() => Done()
  79. }
  80. /** @since 7.0.1 */
  81. def mapM[B](f: A => M[B])(implicit M: Monad[M]): StreamT[M, B] = stepBind[B] {
  82. case Yield(a, s) => M.map(f(a))(Yield(_, s() mapM f))
  83. case Skip(s) => M.point(Skip(s() mapM f))
  84. case Done() => M.point(Done())
  85. }
  86. def foldLeft[B](z: B)(f: (B, A) => B)(implicit M: Monad[M]): M[B] =
  87. M.bind(step) {
  88. case Yield(a, s) => s().foldLeft(f(z, a))(f)
  89. case Skip(s) => s().foldLeft(z)(f)
  90. case Done() => M.point(z)
  91. }
  92. def foldLeftRec[B](z: B)(f: (B, A) => B)(implicit M: BindRec[M]): M[B] =
  93. M.tailrecM((() => this, z))(sb => M.map(sb._1().step) {
  94. case Yield(a, s) => -\/((s, f(sb._2, a)))
  95. case Skip(s) => -\/((s, sb._2))
  96. case Done() => \/-(sb._2)
  97. })
  98. /**
  99. * **Warning:** Requires evaluation of the whole stream. Depending on
  100. * the monad `M`, the evaluation will happen either immediately, or
  101. * will be deferred until the resulting `LazyList` is extracted from the
  102. * returned `M`.
  103. */
  104. def toLazyList(implicit M: Monad[M]): M[LazyList[A]] = M.map(rev)(_.reverse)
  105. /**
  106. * **Warning:** Requires evaluation of the whole stream. Depending on
  107. * the monad `M`, the evaluation will happen either immediately, or
  108. * will be deferred until the resulting `LazyList` is extracted from the
  109. * returned `M`.
  110. */
  111. def toLazyListRec(implicit M: BindRec[M]): M[LazyList[A]] = M.map(revRec)(_.reverse)
  112. /**
  113. * Converts this `StreamT` to a lazy `LazyList`, i.e. without forcing
  114. * evaluation of all elements. Note, however, that at least one element
  115. * of this stream will be evaluated, and depending on the structure of
  116. * this stream, up to two elements might be evaluated.
  117. */
  118. def asLazyList(implicit ev: M[Step[A, StreamT[M, A]]] === Id[Step[A, StreamT[Id, A]]]): LazyList[A] = {
  119. def go(s: StreamT[Id, A]): LazyList[A] = s.unconsRec match {
  120. case None => LazyList.empty[A]
  121. case Some((a, s1)) => LazyList.cons(a, go(s1))
  122. }
  123. go(StreamT(ev(step)))
  124. }
  125. def foldRight[B](z: => B)(f: (=> A, => B) => B)(implicit M: Monad[M]): M[B] =
  126. M.map(rev) {
  127. _.foldLeft(z)((a, b) => f(b, a))
  128. }
  129. def foldRightRec[B](z: => B)(f: (=> A, => B) => B)(implicit M: BindRec[M]): M[B] =
  130. M.map(revRec) {
  131. _.foldLeft(z)((a, b) => f(b, a))
  132. }
  133. /**
  134. * `foldRight` with potential to terminate early, e.g. on an infinite stream.
  135. */
  136. def foldRightM[B](z: => M[B])(f: (=> A, => M[B]) => M[B])(implicit M: Monad[M]): M[B] =
  137. M.bind(step) {
  138. case Yield(a, s) => f(a, s().foldRightM(z)(f))
  139. case Skip(s) => s().foldRightM(z)(f)
  140. case Done() => z
  141. }
  142. def foldMap[B](f: A => B)(implicit M: Foldable[M], B: Monoid[B]): B =
  143. M.foldMap(step) {
  144. case Yield(a, s) => B.append(f(a), s().foldMap(f))
  145. case Skip(s) => s().foldMap(f)
  146. case Done() => B.zero
  147. }
  148. def length(implicit m: Monad[M]): M[Int] =
  149. foldLeft(0)((c, a) => 1 + c)
  150. def lengthRec(implicit M: BindRec[M]): M[Int] =
  151. foldLeftRec(0)((c, a) => 1 + c)
  152. def foreach(f: A => M[Unit])(implicit M: Monad[M]): M[Unit] = M.bind(step) {
  153. case Yield(a,s) => M.bind(f(a))(_ => s() foreach f)
  154. case Skip(s) => s().foreach(f)
  155. case Done() => M.pure(())
  156. }
  157. def foreachRec(f: A => M[Unit])(implicit M: Monad[M], B: BindRec[M]): M[Unit] =
  158. B.tailrecM(() => this)(s => M.bind(s().step) {
  159. case Yield(a, s1) => M.map(f(a))(_ => -\/(s1))
  160. case Skip(s1) => M.pure(-\/(s1))
  161. case Done() => M.pure(\/-(()))
  162. })
  163. private def stepMap[B](f: Step[A, StreamT[M, A]] => Step[B, StreamT[M, B]])(implicit M: Functor[M]): StreamT[M, B] = StreamT(M.map(step)(f))
  164. private def stepBind[B](f: Step[A, StreamT[M, A]] => M[Step[B, StreamT[M, B]]])(implicit M: Monad[M]): StreamT[M, B] = StreamT(M.bind(step)(f))
  165. private def rev(implicit M: Monad[M]): M[LazyList[A]] = {
  166. def loop(xs: StreamT[M, A], ys: LazyList[A]): M[LazyList[A]] =
  167. M.bind(xs.step) {
  168. case Yield(a, s) => loop(s(), a #:: ys)
  169. case Skip(s) => loop(s(), ys)
  170. case Done() => M.point(ys)
  171. }
  172. loop(this, LazyList.empty)
  173. }
  174. private def revRec(implicit M: BindRec[M]): M[LazyList[A]] =
  175. M.tailrecM((() => this, LazyList.empty[A])) { case (xs, ys) =>
  176. M.map(xs().step) {
  177. case Yield(a, s) => -\/((s, a #:: ys))
  178. case Skip(s) => -\/((s, ys))
  179. case Done() => \/-(ys)
  180. }
  181. }
  182. }
  183. //
  184. // Prioritized Implicits for type class instances
  185. //
  186. sealed abstract class StreamTInstances0 {
  187. implicit def StreamTInstance1[F[_]](implicit F0: Functor[F]): Bind[StreamT[F, *]] with Plus[StreamT[F, *]] =
  188. new StreamTInstance1[F] {
  189. implicit def F: Functor[F] = F0
  190. }
  191. implicit def StreamTSemigroup[F[_], A](implicit F0: Functor[F]): Semigroup[StreamT[F, A]] =
  192. new StreamTSemigroup[F, A] {
  193. implicit def F: Functor[F] = F0
  194. }
  195. }
  196. sealed abstract class StreamTInstances extends StreamTInstances0 {
  197. implicit def StreamTMonoid[F[_], A](implicit F0: Applicative[F]): Monoid[StreamT[F, A]] =
  198. new StreamTMonoid[F, A] {
  199. implicit def F: Applicative[F] = F0
  200. }
  201. implicit def StreamTMonadPlus[F[_]](implicit F0: Applicative[F]): MonadPlus[StreamT[F, *]] =
  202. new StreamTMonadPlus[F] {
  203. implicit def F: Applicative[F] = F0
  204. }
  205. implicit def StreamTEqual[F[_], A](implicit E: Equal[F[LazyList[A]]], F: Monad[F]): Equal[StreamT[F, A]] = E.contramap((_: StreamT[F, A]).toLazyList)
  206. implicit def StreamTShow[F[_], A](implicit E: Show[F[LazyList[A]]], F: Monad[F]): Show[StreamT[F, A]] = Contravariant[Show].contramap(E)((_: StreamT[F, A]).toLazyList)
  207. implicit val StreamTHoist: Hoist[StreamT] = new StreamTHoist {}
  208. implicit def StreamTFoldable[F[_]: Foldable]: Foldable[StreamT[F, *]] =
  209. new Foldable[StreamT[F, *]] with Foldable.FromFoldMap[StreamT[F, *]] {
  210. override def foldMap[A, M: Monoid](s: StreamT[F, A])(f: A => M) = s.foldMap(f)
  211. }
  212. }
  213. object StreamT extends StreamTInstances {
  214. def apply[M[_], A](step: M[Step[A, StreamT[M, A]]]): StreamT[M, A] = new StreamT[M, A](step)
  215. def empty[M[_], A](implicit M: Applicative[M]): StreamT[M, A] = new StreamT[M, A](M point Done())
  216. def fromLazyList[M[_], A](mas: M[LazyList[A]])(implicit M: Applicative[M]): StreamT[M, A] = {
  217. def loop(as: LazyList[A]): Step[A, StreamT[M, A]] = as match {
  218. case head #:: tail => Yield(head, apply(M.point(loop(tail))))
  219. case _ => Done()
  220. }
  221. apply[M, A](M.map(mas)(loop))
  222. }
  223. def unfoldM[M[_],A,B](start: B)(f: B => M[Option[(A,B)]])(implicit M: Functor[M]): StreamT[M,A] =
  224. StreamT[M,A](M.map(f(start)) {
  225. case Some((a, b)) => Yield(a, unfoldM(b)(f))
  226. case None => Done()
  227. })
  228. def unfold[A,B](b: B)(f: B => Option[(A,B)]): StreamT[Id,A] = unfoldM[Id,A,B](b)(f)
  229. def fromIterable[A](s: Iterable[A]): StreamT[Id,A] = {
  230. def stepper(b: Iterable[A]): Option[(A,Iterable[A])] = if (b.isEmpty) None else Some((b.head, b.tail))
  231. unfold(s)(stepper)
  232. }
  233. def wrapEffect[M[_]:Functor,A](m: M[StreamT[M,A]]): StreamT[M,A] = StreamT(Functor[M].map(m)(Skip(_)))
  234. def runStreamT[S,A](stream : StreamT[State[S, *],A], s0: S): StreamT[Id,A] =
  235. StreamT[Id,A]({
  236. val (a, s) = stream.step(s0)
  237. s match {
  238. case Yield(a1, s1) => Yield(a1, runStreamT(s1(), a))
  239. case Skip(s1) => Skip(runStreamT(s1(), a))
  240. case Done() => Done()
  241. }
  242. })
  243. sealed abstract class Step[A, S] extends Product with Serializable
  244. final case class Yield[A, S](a: A, s: () => S) extends Step[A, S]
  245. object Yield {
  246. def apply[A, S](a: A, s: => S): Step[A, S] = new Yield(a, () => s)
  247. }
  248. final case class Skip[A, S](s: () => S) extends Step[A, S]
  249. object Skip {
  250. def apply[A, S](s: => S): Step[A, S] = new Skip(() => s)
  251. }
  252. sealed abstract case class Done[A, S]() extends Step[A, S]
  253. object Done {
  254. def apply[A, S](): Step[A, S] = done_.asInstanceOf[Done[A, S]]
  255. // https://github.com/scala/bug/issues/11953
  256. private[this] final val done_ : Done[Nothing, Nothing] = new Done[Nothing, Nothing]{}
  257. }
  258. }
  259. //
  260. // Implementation traits for type class instances
  261. //
  262. private trait StreamTInstance1[F[_]] extends Bind[StreamT[F, *]] with Plus[StreamT[F, *]] {
  263. implicit def F: Functor[F]
  264. override final def map[A, B](fa: StreamT[F, A])(f: A => B) =
  265. fa map f
  266. override final def bind[A, B](fa: StreamT[F, A])(f: A => StreamT[F, B]) =
  267. fa flatMap f
  268. override final def plus[A](a: StreamT[F, A], b: => StreamT[F, A]) =
  269. a ++ b
  270. }
  271. private trait StreamTSemigroup[F[_], A] extends Semigroup[StreamT[F, A]] {
  272. implicit def F: Functor[F]
  273. def append(f1: StreamT[F, A], f2: => StreamT[F, A]): StreamT[F, A] = f1 ++ f2
  274. }
  275. private trait StreamTMonoid[F[_], A] extends Monoid[StreamT[F, A]] with StreamTSemigroup[F, A] {
  276. implicit def F: Applicative[F]
  277. def zero: StreamT[F, A] = StreamT.empty[F, A]
  278. }
  279. private trait StreamTMonadPlus[F[_]] extends MonadPlus[StreamT[F, *]] with StreamTInstance1[F] {
  280. implicit def F: Applicative[F]
  281. def point[A](a: => A): StreamT[F, A] = a :: StreamT.empty[F, A]
  282. def empty[A]: StreamT[F, A] = StreamT.empty
  283. }
  284. private trait StreamTHoist extends Hoist[StreamT] {
  285. import StreamT._
  286. implicit def apply[G[_] : Monad]: Monad[StreamT[G, *]] = StreamTMonadPlus[G]
  287. def liftM[G[_], A](a: G[A])(implicit G: Monad[G]): StreamT[G, A] =
  288. StreamT[G, A](G.map(a)(Yield(_, empty[G, A](G))))
  289. override def wrapEffect[G[_]: Monad, A](a: G[StreamT[G, A]]): StreamT[G, A] = StreamT.wrapEffect(a)
  290. def hoist[M[_], N[_]](f: M ~> N)(implicit M: Monad[M]): StreamT[M, *] ~> StreamT[N, *] =
  291. λ[StreamT[M, *] ~> StreamT[N, *]](a =>
  292. StreamT(f(M.map(a.step) {
  293. case Yield(a, s) => Yield(a, hoist(f).apply(s()))
  294. case Skip(s) => Skip(hoist(f).apply(s()))
  295. case Done() => Done()
  296. }
  297. )))
  298. }