Permalink
Browse files

Delete MonadPartialOrder

A review from Kmett:

> The category of monads isn't thin
> It isn't a partial order
> Reader Int -> Reader Int has a whole boatload of monad homomorphisms
> Writer (Any,Any) to itself can flip the order keep one or the other and duplicate, reset to False, etc
> All of those are distinct monad homomorphisms
> MonadPO isn't a real thing
> It is pseudo math

We had 3 votes to delete this on IRC after this conversation.
  • Loading branch information...
puffnfresh committed Aug 8, 2017
1 parent 6eddfe5 commit e528b357591b2f40998b29d812df715110c06f2e
@@ -27,19 +27,5 @@ object MonadState {
////
def promotedMonadState[G[_], F[_], S](
implicit
mpo: MonadPartialOrder[G, F],
ms: MonadState[F, S]
): MonadState[G, S] = new MonadState[G, S] {
override def get: G[S] = mpo.promote(ms.get)
override def put(s: S): G[Unit] = mpo.promote(ms put s)
override def point[A](a: => A): G[A] = mpo.MG point a
override def bind[A, B](ga: G[A])(f: A => G[B]): G[B] = mpo.MG.bind(ga)(f)
}
////
}
@@ -41,50 +41,3 @@ trait Hoist[F[_[_], _]] extends MonadTrans[F] {
object Hoist {
def apply[F[_[_], _]](implicit F: Hoist[F]): Hoist[F] = F
}
/**
* This trait establishes a partial order among monads. A "bigger" monad
* is one that does all of the effects of the "smaller" as part of its
* execution.
*/
trait MonadPartialOrder[G[_], F[_]] extends NaturalTransformation[F, G] { self =>
implicit val MG: Monad[G]
implicit val MF: Monad[F]
def apply[A](m2: F[A]) = promote(m2)
def promote[A](m2: F[A]): G[A]
def compose[M[_]](mo: MonadPartialOrder[M, G]): MonadPartialOrder[M, F] =
new MonadPartialOrder[M, F] {
val MG = mo.MG
val MF = self.MF
def promote[A](m2: F[A]) = mo.promote(self.promote(m2))
}
def transform[T[_[_], _]: MonadTrans]: MonadPartialOrder[T[G, ?], F] =
new MonadPartialOrder[T[G, ?], F] {
val MG = MonadTrans[T].apply[G](self.MG)
val MF = self.MF
def promote[A](m2: F[A]) = MonadTrans[T].liftM(self.promote(m2))(self.MG)
}
}
sealed abstract class MonadPartialOrderFunctions1 {
implicit def transitive[G[_], F[_], E[_]](implicit e1: MonadPartialOrder[G, F], e2: MonadPartialOrder[F, E]): MonadPartialOrder[G, E] =
e2 compose e1
}
sealed abstract class MonadPartialOrderFunctions extends MonadPartialOrderFunctions1 {
// the identity ordering
implicit def id[M[_]: Monad]: MonadPartialOrder[M, M] =
new MonadPartialOrder[M, M] {
val MG = Monad[M]
val MF = Monad[M]
def promote[A](m: M[A]) = m
}
implicit def transformer[M[_]: Monad, F[_[_], _]: MonadTrans]: MonadPartialOrder[F[M, ?], M] =
id[M].transform[F]
}
object MonadPartialOrder extends MonadPartialOrderFunctions
@@ -118,8 +118,6 @@ package object scalaz {
type ∨[A, B] = A \/ B
type |>=|[G[_], F[_]] = MonadPartialOrder[G, F]
type ReaderT[F[_], E, A] = Kleisli[F, E, A]
val ReaderT = Kleisli
type =?>[E, A] = Kleisli[Option, E, A]
@@ -1,7 +1,7 @@
package scalaz.example
object IterateeUsage extends App {
import scalaz._, Scalaz._, MonadPartialOrder._
import scalaz._, Scalaz._
import iteratee._, Iteratee._
import effect._
@@ -18,7 +18,7 @@ trait Enumeratee2TFunctions {
@inline private def lift[J, K, F[_]: Monad, A](iter: IterateeT[K, F, A]): IterateeT[J, IterateeT[K, F, ?], A] =
IterateeT.IterateeTMonadTrans[J].liftM[IterateeT[K, F, ?], A](iter)
def cogroupI[J, K, F[_]](implicit M: Monad[F], order: (J, K) => Ordering): Enumeratee2T[J, K, Either3[J, (J, K), K], F] =
def cogroupI[J, K, F[_]](compare: (J, K) => Ordering)(implicit M: Monad[F]): Enumeratee2T[J, K, Either3[J, (J, K), K], F] =
new Enumeratee2T[J, K, Either3[J, (J, K), K], F] {
def apply[A] = {
// Used to 'replay' values from the right for when values from the left order equal
@@ -27,8 +27,8 @@ trait Enumeratee2TFunctions {
def advance(j: J, buf: List[K], s: StepT[Either3[J, (J, K), K], F, A]): IterateeT[Either3[J,(J, K),K],F,A] = {
s mapCont { contf =>
buf match {
case k :: Nil if order(j, k) == EQ => contf(elInput(Middle3((j, k))))
case k :: ks if order(j, k) == EQ => contf(elInput(Middle3((j, k)))) >>== (advance(j, ks, _))
case k :: Nil if compare(j, k) == EQ => contf(elInput(Middle3((j, k))))
case k :: ks if compare(j, k) == EQ => contf(elInput(Middle3((j, k)))) >>== (advance(j, ks, _))
case _ => contf(elInput(Left3(j)))
}
}
@@ -41,13 +41,13 @@ trait Enumeratee2TFunctions {
leftOpt <- peek[J, IterateeM]
rightOpt <- lift[J, K, F, Option[K]](peek[K, F])
a <- (leftOpt, rightOpt) match {
case (left, Some(right)) if left.forall(order(_, right) == GT) =>
case (left, Some(right)) if left.forall(compare(_, right) == GT) =>
for {
_ <- lift[J, K, F, Option[K]](head[K, F])
a <- iterateeT[J, IterateeM, StepM[A]](contf(elInput(Right3(right))) >>== (step(_, Nil).value))
} yield a
case (Some(left), right) if right.forall(order(left, _) == LT) =>
case (Some(left), right) if right.forall(compare(left, _) == LT) =>
for {
_ <- head[J, IterateeM]
a <- iterateeT[J, IterateeM, StepM[A]](advance(left, rbuf, scont(contf)) >>== (step(_, rbuf).value))
@@ -56,7 +56,7 @@ trait Enumeratee2TFunctions {
case (Some(left), Some(right)) =>
for {
_ <- lift[J, K, F, Option[K]](head[K, F])
a <- step(s, if (rbuf.headOption.exists(order(left, _) == EQ)) right :: rbuf else right :: Nil)
a <- step(s, if (rbuf.headOption.exists(compare(left, _) == EQ)) right :: rbuf else right :: Nil)
} yield a
case _ => done[J, IterateeM, StepM[A]](s, eofInput)
@@ -71,7 +71,7 @@ trait Enumeratee2TFunctions {
}
}
def joinI[J, K, F[_]](implicit M: Monad[F], ord: (J, K) => Ordering): Enumeratee2T[J, K, (J, K), F] =
def joinI[J, K, F[_]](compare: (J, K) => Ordering)(implicit M: Monad[F]): Enumeratee2T[J, K, (J, K), F] =
new Enumeratee2T[J, K, (J, K), F] {
def apply[A] = {
def cstep(step: StepT[(J, K), F, A]): StepT[Either3[J, (J, K), K], F, StepT[(J, K), F, A]] = step.fold(
@@ -83,7 +83,7 @@ trait Enumeratee2TFunctions {
done = (a, r) => sdone(sdone(a, if (r.isEof) eofInput else emptyInput), if (r.isEof) eofInput else emptyInput)
)
(step: StepT[(J, K), F, A]) => cogroupI[J, K, F].apply(cstep(step)) flatMap { endStep[J, K, (J, K), F, A] }
(step: StepT[(J, K), F, A]) => cogroupI[J, K, F](compare).apply(cstep(step)) flatMap { endStep[J, K, (J, K), F, A] }
}
}
@@ -120,7 +120,7 @@ trait Enumeratee2TFunctions {
}
}
def parFoldI[J, K, F[_]](f: K => J)(implicit order: (J, K) => Ordering, m: Monoid[J], M: Monad[F]): Enumeratee2T[J, K, J, F] =
def parFoldI[J, K, F[_]](compare: (J, K) => Ordering)(f: K => J)(implicit m: Monoid[J], M: Monad[F]): Enumeratee2T[J, K, J, F] =
new Enumeratee2T[J, K, J, F] {
def apply[A] = {
def cstep(step: StepT[J, F, A]): StepT[Either3[J, (J, K), K], F, StepT[J, F, A]] = step.fold(
@@ -136,7 +136,7 @@ trait Enumeratee2TFunctions {
done = (a, r) => sdone(sdone(a, if (r.isEof) eofInput else emptyInput), if (r.isEof) eofInput else emptyInput)
)
(step: StepT[J, F, A]) => cogroupI[J, K, F].apply(cstep(step)) flatMap { endStep[J, K, J, F, A] }
(step: StepT[J, F, A]) => cogroupI[J, K, F](compare).apply(cstep(step)) flatMap { endStep[J, K, J, F, A] }
}
}
@@ -56,7 +56,7 @@ abstract class EnumeratorP[E, F[_]] { self =>
}
def join(other: EnumeratorP[E, F])(implicit order: Order[E], m: Monad[F]): EnumeratorP[(E, E), F] =
EnumeratorP.joinE[E, E, F](m, order.order).apply(self, other)
EnumeratorP.joinE[E, E, F](order.order).apply(self, other)
def merge(other: EnumeratorP[E, F])(implicit ord: Order[E], m: Monad[F]): EnumeratorP[E, F] =
EnumeratorP.mergeE[E, F].apply(self, other)
@@ -95,17 +95,17 @@ trait EnumeratorPFunctions {
}
}
def cogroupE[J, K, F[_]](implicit M: Monad[F], ord: (J, K) => Ordering): (EnumeratorP[J, F], EnumeratorP[K, F]) => EnumeratorP[Either3[J, (J, K), K], F] =
def cogroupE[J, K, F[_]](compare: (J, K) => Ordering)(implicit M: Monad[F]): (EnumeratorP[J, F], EnumeratorP[K, F]) => EnumeratorP[Either3[J, (J, K), K], F] =
liftE2[J, K, Either3[J, (J, K), K], F] {
new ForallM[λ[β[_] => Enumeratee2T[J, K, Either3[J, (J, K), K], β]]] {
def apply[G[_] : Monad] = cogroupI[J, K, G]
def apply[G[_] : Monad] = cogroupI[J, K, G](compare)
}
}
def joinE[J, K, F[_]](implicit M: Monad[F], ord: (J, K) => Ordering): (EnumeratorP[J, F], EnumeratorP[K, F]) => EnumeratorP[(J, K), F] =
def joinE[J, K, F[_]](compare: (J, K) => Ordering)(implicit M: Monad[F]): (EnumeratorP[J, F], EnumeratorP[K, F]) => EnumeratorP[(J, K), F] =
liftE2[J, K, (J, K), F] {
new ForallM[λ[β[_] => Enumeratee2T[J, K, (J, K), β]]] {
def apply[G[_] : Monad] = joinI[J, K, G]
def apply[G[_] : Monad] = joinI[J, K, G](compare)
}
}
@@ -22,10 +22,8 @@ trait EnumeratorT[E, F[_]] { self =>
def flatMap[B](f: E => EnumeratorT[B, F])(implicit M1: Monad[F]): EnumeratorT[B, F] =
EnumerateeT.flatMap(f) run self
def flatten[B, G[_]](implicit ev: E =:= G[B], MO: F |>=| G): EnumeratorT[B, F] = {
import MO._
flatMap(e => EnumeratorT.enumeratorTMonadTrans.liftM(MO.promote(ev(e))))
}
def flatten[B](implicit ev: E =:= F[B], F: Monad[F]): EnumeratorT[B, F] =
flatMap(e => EnumeratorT.enumeratorTMonadTrans.liftM(ev(e)))
def bindM[B, G[_]](f: E => G[EnumeratorT[B, F]])(implicit F: Monad[F], G: Monad[G]): F[G[EnumeratorT[B, F]]] = {
import scalaz.syntax.semigroup._
@@ -142,9 +140,8 @@ trait EnumeratorTFunctions {
}
}
def enumIterator[E, F[_]](x: => Iterator[E])(implicit MO: MonadPartialOrder[F, IO]) : EnumeratorT[E, F] =
def enumIterator[E, F[_]](x: => Iterator[E])(implicit F: MonadIO[F]) : EnumeratorT[E, F] =
new EnumeratorT[E, F] {
import MO._
def apply[A] = {
def go(xs: Iterator[E])(s: StepT[E, F, A]): IterateeT[E, F, A] =
if(xs.isEmpty) s.pointI
@@ -158,9 +155,8 @@ trait EnumeratorTFunctions {
}
}
def enumIoSource[T, E, F[_]](get : () => IoExceptionOr[T], gotdata : IoExceptionOr[T] => Boolean, render : T => E)(implicit MO: MonadPartialOrder[F, IO]): EnumeratorT[IoExceptionOr[E], F] =
def enumIoSource[T, E, F[_]](get : () => IoExceptionOr[T], gotdata : IoExceptionOr[T] => Boolean, render : T => E)(implicit F: MonadIO[F]): EnumeratorT[IoExceptionOr[E], F] =
new EnumeratorT[IoExceptionOr[E], F] {
import MO._
def apply[A] = (s: StepT[IoExceptionOr[E], F, A]) =>
s.mapCont(
k => {
@@ -171,14 +167,14 @@ trait EnumeratorTFunctions {
)
}
def enumReader[F[_]](r: => java.io.Reader)(implicit MO: MonadPartialOrder[F, IO]): EnumeratorT[IoExceptionOr[Char], F] = {
def enumReader[F[_]](r: => java.io.Reader)(implicit F: MonadIO[F]): EnumeratorT[IoExceptionOr[Char], F] = {
lazy val src = r
enumIoSource(get = () => IoExceptionOr(src.read),
gotdata = (i: IoExceptionOr[Int]) => i exists (_ != -1),
render = ((n: Int) => n.toChar))
}
def enumInputStream[F[_]](is: => java.io.InputStream)(implicit MO: MonadPartialOrder[F, IO]): EnumeratorT[IoExceptionOr[Byte], F] = {
def enumInputStream[F[_]](is: => java.io.InputStream)(implicit F: MonadIO[F]): EnumeratorT[IoExceptionOr[Byte], F] = {
lazy val src = is
enumIoSource(get = () => IoExceptionOr(src.read),
gotdata = (i: IoExceptionOr[Int]) => i exists (_ != -1),
@@ -71,12 +71,12 @@ sealed abstract class IterateeT[E, F[_], A] {
* The monad for G must perform all the effects of F as part of its evaluation; in the trivial case, of course
* F and G will have the same monad.
*/
def advance[EE, AA, G[_]](f: StepT[E, F, A] => IterateeT[EE, G, AA])(implicit MO: G |>=| F): IterateeT[EE, G, AA] = {
iterateeT(MO.MG.bind(MO.promote(value))(s => f(s).value))
def advance[EE, AA, G[_]](f: StepT[E, F, A] => IterateeT[EE, G, AA], trans: F ~> G)(implicit G: Bind[G]): IterateeT[EE, G, AA] = {
iterateeT(G.bind(trans(value))(s => f(s).value))
}
def advanceT[EE, AA, G[_]](f: StepT[E, F, A] => G[StepT[EE, F, AA]])(implicit MO: G |>=| F): G[StepT[EE, F, AA]] = {
MO.MG.bind(MO.promote(value))(s => f(s))
def advanceT[EE, AA, G[_]](f: StepT[E, F, A] => G[StepT[EE, F, AA]], trans: F ~> G)(implicit G: Bind[G]): G[StepT[EE, F, AA]] = {
G.bind(trans(value))(s => f(s))
}
/**
@@ -78,16 +78,4 @@ object StateTTest extends SpecLite {
.foldLeft(StateT((s:Int) => Trampoline.done((s,s))))( (a,b) => a.flatMap(_ => b))
4000 must_=== result(0).run._1
}
"MonadState must be derived for any stack of Monads" in {
type StateStack[A] = State[Int, A]
type ListStack[A] = ListT[StateStack, A]
// `promotedMonadState` implicit instance had to be reverted (see #1308).
// Call `promotedMonadState` explicitly for now.
//val ms = MonadState[ListStack, Int]
val ms = MonadState.promotedMonadState[ListStack, StateStack, Int]
ms.get.run.eval(1) must_=== List(1)
}
}
@@ -12,16 +12,21 @@ object Enumeratee2TTest extends SpecLite {
implicit val ls = listShow[Either3[Int, (Int, Int), Int]]
implicit val v = IterateeT.IterateeTMonad[Int, Id]
implicit val vt = IterateeT.IterateeTMonadTrans[Int]
implicit val intO = Order[Int].order _
val intO = Order[Int].order _
type StepM[A] = StepT[Int, Id, A]
type IterateeM[A] = IterateeT[Int, Id, A]
val vtLift = new (Id ~> IterateeM) {
def apply[A](a: Id[A]): IterateeM[A] =
vt.liftM(a)
}
"join equal pairs" in {
val enum = enumStream[Int, IterateeM](Stream(1, 3, 5, 7))
val enum2 = enumStream[Int, Id](Stream(2, 3, 4, 5, 6))
val outer = joinI[Int, Int, Id].apply(consume[(Int, Int), Id, List].value) &= enum
val outer = joinI[Int, Int, Id](intO).apply(consume[(Int, Int), Id, List].value) &= enum
val inner = outer.run &= enum2
inner.run.pointI.run must_===(List((3, 3), (5, 5)))
@@ -35,7 +40,7 @@ object Enumeratee2TTest extends SpecLite {
val enum2 = enumStream[Int, Id](Stream(2, 3, 4, 5, 5, 6, 8, 8))
val consumer = consume[E3I, Id, List]
val outer = consumer.advance[Int, StepT[E3I, Id, E3LI], IterateeM](cogroupI[Int, Int, Id].apply[E3LI])
val outer = consumer.advance[Int, StepT[E3I, Id, E3LI], IterateeM](cogroupI[Int, Int, Id](intO).apply[E3LI], vtLift)
val outer2 = outer &= enum
val inner = outer2.run &= enum2
@@ -90,7 +95,7 @@ object Enumeratee2TTest extends SpecLite {
}
val consumer = consume[(Int, Int), Id, List]
val producer = joinE[Int, Int, Id].apply(enum1p, enum2p).apply[Id](id)
val producer = joinE[Int, Int, Id](intO).apply(enum1p, enum2p).apply[Id](id)
(consumer &= producer).run must_===(List(
(1, 1), (1, 1), (1, 1)
))
@@ -15,7 +15,7 @@ object EnumeratorPTest extends SpecLite {
val enum = enumPStream[Int, Id](Stream(1, 3, 3, 5, 7, 8, 8))
val enum2 = enumPStream[Int, Id](Stream(2, 3, 4, 5, 5, 6, 8, 8))
val cf = cogroupE[Int, Int, Id]
val cf = cogroupE[Int, Int, Id](Order[Int].order)
val enumR = cf(enum, enum2)
(consume[Either3[Int, (Int, Int), Int], Id, List] &= enumR.apply[Id](id)).run must_===(List(
@@ -40,7 +40,7 @@ object EnumeratorPTest extends SpecLite {
val enum2 = enumPStream[Int, Id](Stream(2, 3, 4, 5, 5, 6, 8, 8))
val enum3 = enumPStream[Int, Id](Stream(3, 5, 8))
val cf = cogroupE[Int, Int, Id]
val cf = cogroupE[Int, Int, Id](Order[Int].order)
val enumR = cf(cf(enum, enum2) map { _.fold(identity[Int], _._1, identity[Int]) }, enum3)
(consume[Either3[Int, (Int, Int), Int], Id, List] &= enumR.apply[Id](id)).run must_===(List(
@@ -23,7 +23,7 @@ object EnumeratorTTest extends SpecLite {
"Issue #553" in {
import std.list._
val xs = (1 to 10).map(List(_)).toList
val e = enumIterator(xs.iterator)
val e = enumIterator[List[Int], IO](xs.iterator)
(Iteratee.sum[List[Int], IO] &= e).run.unsafePerformIO must_===(xs.flatten)
(Iteratee.sum[List[Int], IO] &= e).run.unsafePerformIO must_===(xs.flatten)
}

0 comments on commit e528b35

Please sign in to comment.