/core/src/main/scala/scalaz/ListT.scala
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}