/core/src/main/scala/scalaz/ListT.scala

http://github.com/scalaz/scalaz · Scala · 205 lines · 136 code · 59 blank · 10 comment · 0 complexity · a381b4b7ea40d5b708501361adddac33 MD5 · raw file

  1. package scalaz
  2. import Maybe.just
  3. /**
  4. * ListT monad transformer.
  5. */
  6. final case class ListT[M[_], A](run: M[IList[A]]){
  7. def uncons(implicit M: Applicative[M]): M[Maybe[(A, ListT[M, A])]] = {
  8. M.map(run) {
  9. case INil() => Maybe.empty
  10. case ICons(listHead, listTail) => just((listHead, new ListT(M.point(listTail))))
  11. }
  12. }
  13. def ::(a: A)(implicit M: Functor[M]) : ListT[M, A] = new ListT(M.map(run)(list => a :: list))
  14. def collect[B](pf: PartialFunction[A,B])(implicit M: Functor[M]): ListT[M, B] = new ListT(M.map(run)(_.collect(pf)))
  15. def isEmpty(implicit M: Functor[M]) : M[Boolean] = M.map(run)(_.isEmpty)
  16. def headOption(implicit M: Functor[M]) : OptionT[M, A] = new OptionT(M.map(run)(_.headOption))
  17. def find(predicate: A => Boolean)(implicit M: Functor[M]) : MaybeT[M, A] = new MaybeT(M.map(run)(_.find(predicate)))
  18. def headMaybe(implicit M: Functor[M]) : MaybeT[M, A] = new MaybeT(M.map(run)(_.headMaybe))
  19. def tailM(implicit M: Applicative[M]) : M[ListT[M, A]] = M.map(uncons)(_.map(_._2).toOption.get)
  20. def filter(p: A => Boolean)(implicit M: Functor[M]): ListT[M, A] = new ListT(M.map(run)(_.filter(p)))
  21. def drop(n: Int)(implicit M: Functor[M]) : ListT[M, A] = new ListT(M.map(run)(_.drop(n)))
  22. def dropWhile(p: A => Boolean)(implicit M: Functor[M]) : ListT[M, A] = new ListT(M.map(run)(_.dropWhile(p)))
  23. def take(n: Int)(implicit M: Functor[M]) : ListT[M, A] = new ListT(M.map(run)(_.take(n)))
  24. def takeWhile(p: A => Boolean)(implicit M: Functor[M]) : ListT[M, A] = new ListT(M.map(run)(_.takeWhile(p)))
  25. def ++(bs: => ListT[M, A])(implicit M: Bind[M]) : ListT[M, A] = new ListT(M.bind(run){list1 =>
  26. M.map(bs.run){list2 =>
  27. list1 ++ list2
  28. }
  29. })
  30. def flatMap[B](f: A => ListT[M, B])(implicit M: Monad[M]) : ListT[M, B] =
  31. new ListT(M.bind(run)(Foldable[IList].foldMap(_)(f).run))
  32. def flatMapF[B](f: A => M[IList[B]])(implicit M: Monad[M]) : ListT[M, B] = flatMap(f andThen ListT.apply)
  33. def map[B](f: A => B)(implicit M: Functor[M]): ListT[M, B] = new ListT(
  34. M.map(run)(_.map(f))
  35. )
  36. def mapF[B](f: A => M[B])(implicit M: Monad[M]): ListT[M, B] = {
  37. flatMapF {
  38. f andThen (mb => M.map(mb)(b => IList(b)))
  39. }
  40. }
  41. def mapT[F[_], B](f: M[IList[A]] => F[IList[B]]): ListT[F, B] =
  42. ListT(f(run))
  43. /**Don't use iteratively! */
  44. def tail(implicit M: Functor[M]) : ListT[M, A] = new ListT(M.map(run)(_.tailMaybe.toOption.get))
  45. def tailMaybe(implicit M: Functor[M]) : ListT[Lambda[a => M[Maybe[a]]], A] = new ListT[Lambda[a => M[Maybe[a]]], A](M.map(run)(_.tailMaybe))
  46. def foldLeft[B](z: => B)(f: (=> B, => A) => B)(implicit M: Functor[M]) : M[B] = M.map(run)(_.foldLeft(z){(left, right) => f(left, right)})
  47. def toIList : M[IList[A]] = run
  48. def toList(implicit M: Functor[M]): M[List[A]] = M.map(run)(_.toList)
  49. def foldRight[B](z: => B)(f: (=> A, => B) => B)(implicit M: Functor[M]) : M[B] = M.map(run)(_.foldRight(z){(right, left) => f(right, left)})
  50. def length(implicit M: Functor[M]) : M[Int] = M.map(run)(_.length)
  51. }
  52. //
  53. // Prioritized Implicits for type class instances
  54. //
  55. sealed abstract class ListTInstances2 {
  56. implicit def listTFunctor[F[_]](implicit F0: Functor[F]): Functor[ListT[F, *]] =
  57. new ListTFunctor[F]{
  58. implicit def F: Functor[F] = F0
  59. }
  60. implicit def listTSemigroup[F[_], A](implicit F0: Bind[F]): Semigroup[ListT[F, A]] =
  61. new ListTSemigroup[F, A]{
  62. implicit def F: Bind[F] = F0
  63. }
  64. }
  65. sealed abstract class ListTInstances1 extends ListTInstances2 {
  66. implicit def listTMonoid[F[_], A](implicit F0: Monad[F]): Monoid[ListT[F, A]] =
  67. new ListTMonoid[F, A] {
  68. implicit def F: Monad[F] = F0
  69. }
  70. }
  71. sealed abstract class ListTInstances extends ListTInstances1 {
  72. implicit def listTMonadPlus[F[_]](implicit F0: Monad[F]): MonadPlus[ListT[F, *]] with Alt[ListT[F, *]] =
  73. new ListTMonadPlus[F] with Alt[ListT[F, *]] {
  74. implicit def F: Monad[F] = F0
  75. def alt[A](a: => ListT[F, A], b: => ListT[F, A]): ListT[F, A] =
  76. plus(a, b)
  77. }
  78. implicit def listTEqual[F[_], A](implicit E: Equal[F[IList[A]]]): Equal[ListT[F, A]] =
  79. E.contramap((_: ListT[F, A]).toIList)
  80. implicit def listTShow[F[_], A](implicit E: Show[F[IList[A]]]): Show[ListT[F, A]] =
  81. Contravariant[Show].contramap(E)((_: ListT[F, A]).toIList)
  82. implicit val listTHoist: Hoist[ListT] =
  83. new ListTHoist {}
  84. implicit def listTDecidable[F[_]](implicit F0: Divisible[F]): Decidable[ListT[F, *]] =
  85. new ListTDecidable[F] {
  86. implicit def F: Divisible[F] = F0
  87. }
  88. }
  89. object ListT extends ListTInstances {
  90. def listT[M[_]]: (λ[α => M[IList[α]]] ~> ListT[M, *]) =
  91. λ[λ[α => M[IList[α]]] ~> ListT[M, *]](
  92. new ListT(_)
  93. )
  94. def empty[M[_], A](implicit M: Applicative[M]): ListT[M, A] =
  95. new ListT[M, A](M.point(INil()))
  96. def fromIList[M[_], A](mas: M[IList[A]]): ListT[M, A] =
  97. new ListT(mas)
  98. def fromList[M[_], A](mas: M[List[A]])(implicit M: Functor[M]): ListT[M, A] =
  99. new ListT(M.map(mas)(IList.fromList))
  100. }
  101. //
  102. // Implementation traits for type class instances
  103. //
  104. private trait ListTDecidable[F[_]] extends Decidable[ListT[F, *]] {
  105. implicit def F: Divisible[F]
  106. override def conquer[A]: ListT[F, A] = ListT(F.conquer)
  107. override def divide2[A1, A2, Z](a1: => ListT[F, A1], a2: => ListT[F, A2])(f: Z => (A1, A2)): ListT[F, Z] =
  108. ListT(F.divide2(a1.run, a2.run)((z: IList[Z]) => Unzip[IList].unzip(z.map(f))))
  109. override def choose2[Z, A1, A2](a1: => ListT[F, A1], a2: => ListT[F, A2])(f: Z => A1 \/ A2): ListT[F, Z] =
  110. ListT(
  111. F.divide2(a1.run, a2.run) (
  112. (z: IList[Z]) => z.map(f)
  113. ./:((IList.empty[A1], IList.empty[A2])) {
  114. case (x, y) => y.fold(a1 => (x._1 :+ a1, x._2), a2 => (x._1, x._2 :+ a2))
  115. }
  116. )
  117. )
  118. }
  119. private trait ListTFunctor[F[_]] extends Functor[ListT[F, *]] {
  120. implicit def F: Functor[F]
  121. override def map[A, B](fa: ListT[F, A])(f: A => B): ListT[F, B] = fa map f
  122. }
  123. private trait ListTSemigroup[F[_], A] extends Semigroup[ListT[F, A]] {
  124. implicit def F: Bind[F]
  125. def append(f1: ListT[F, A], f2: => ListT[F, A]): ListT[F, A] = f1 ++ f2
  126. }
  127. private trait ListTMonoid[F[_], A] extends Monoid[ListT[F, A]] with ListTSemigroup[F, A] {
  128. implicit def F: Monad[F]
  129. def zero: ListT[F, A] = ListT.empty[F, A]
  130. }
  131. private trait ListTMonadPlus[F[_]] extends MonadPlus[ListT[F, *]] with ListTFunctor[F] {
  132. implicit def F: Monad[F]
  133. def bind[A, B](fa: ListT[F, A])(f: A => ListT[F, B]): ListT[F, B] = fa flatMap f
  134. def point[A](a: => A): ListT[F, A] = a :: ListT.empty[F, A]
  135. def empty[A]: ListT[F, A] = ListT.empty[F, A]
  136. def plus[A](a: ListT[F, A], b: => ListT[F, A]): ListT[F, A] = a ++ b
  137. }
  138. private trait ListTHoist extends Hoist[ListT] {
  139. import ListT._
  140. implicit def apply[G[_] : Monad]: Monad[ListT[G, *]] =
  141. listTMonadPlus[G]
  142. def liftM[G[_], A](a: G[A])(implicit G: Monad[G]): ListT[G, A] =
  143. fromIList(G.map(a)(entry => entry :: INil()))
  144. def hoist[M[_], N[_]](f: M ~> N)(implicit M: Monad[M]): ListT[M, *] ~> ListT[N, *] =
  145. λ[ListT[M, *] ~> ListT[N, *]](_ mapT f.apply)
  146. }