PageRenderTime 36ms CodeModel.GetById 1ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 1ms

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