Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

MonadWriter typeclass #93

Closed
wants to merge 18 commits into from

1 participant

@YoEight

Partially a port from Haskell MonadWriter.

It pemits to use Writer Monad Transformer computation without type annotations nightmare

This comes with two implementations: WriterT and ValidationT

Here an example https://gist.github.com/2771406

@YoEight YoEight closed this
@YoEight

I'll make a new branch for avoiding this long commit list.

BTW, after studying on Unapply typeclass, I think I could come up with a nicer syntax by provinding an MonadWriterOps typeclass with those methods:

:++>
:++>>
<++:
<<++:
... and so on, just like WriterT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 25, 2012
  1. @YoEight
Commits on Jan 26, 2012
  1. @YoEight

    cleaning

    YoEight authored
  2. @YoEight

    cleaning

    YoEight authored
  3. @YoEight
Commits on Jan 28, 2012
  1. @YoEight
  2. @YoEight
Commits on Jan 29, 2012
  1. @YoEight

    ValidationT instances refactoring

    YoEight authored
    + tests
  2. @YoEight

    cleaning

    YoEight authored
  3. @YoEight

    A Validation Monad Transformer

    YoEight authored
  4. @YoEight
Commits on May 21, 2012
  1. @YoEight

    Merge branch 'scalaz-seven' of https://github.com/scalaz/scalaz into …

    YoEight authored
    …scalaz-seven
    
    Conflicts:
    	core/src/main/scala/scalaz/ValidationT.scala
    	etc/CONTRIBUTORS
    	scalacheck-binding/src/main/scala/scalaz/scalacheck/ScalazArbitrary.scala
    	tests/src/test/scala/scalaz/ValidationTTest.scala
  2. @YoEight

    MonadWriter typeclass

    YoEight authored
Commits on May 22, 2012
  1. @YoEight
  2. @YoEight

    fix MonadWriter.tell

    YoEight authored
  3. @YoEight

    clean up

    YoEight authored
  4. @YoEight

    clean up

    YoEight authored
  5. @YoEight

    MonadWriter typeclass

    YoEight authored
    MonadWriter WriterT and ValidationT
    
    fix MonadWriter.tell
    
    clean up
    
    clean up
  6. @YoEight
This page is out of date. Refresh to see the latest.
View
14 core/src/main/scala/scalaz/MonadWriter.scala
@@ -0,0 +1,14 @@
+package scalaz
+
+trait MonadWriter[F[_, _], W] extends Monad[({type f[x] = F[W, x]})#f] {
+ implicit def W: Monoid[W]
+
+ def writer[A](v: (W, A)): F[W, A]
+ def tell(w: W): F[W, Unit]
+ def listen[A](fa: F[W, A]): F[W, (A, W)]
+ def pass[A](fa: F[W, (A, W => W)]): F[W, A]
+}
+
+object MonadWriter {
+ def apply[F[_, _], W](implicit F: MonadWriter[F, W]) = F
+}
View
53 core/src/main/scala/scalaz/ValidationT.scala
@@ -76,6 +76,7 @@ sealed trait ValidationT[F[_], E, A] {
}
object ValidationT extends ValidationTFunctions with ValidationTInstances {
+
def apply[F[_], E, A](m: F[Validation[E, A]]): ValidationT[F, E, A] = validationT(m)
sealed trait FailProjectionT[F[_], E, A] {
@@ -118,6 +119,7 @@ object FailProjectionT extends FailProjectionTFunctions {
}
trait ValidationTFunctions {
+
def validationT[F[_], E, A](m: F[Validation[E, A]]): ValidationT[F, E, A] = new ValidationT[F, E, A] {
def run = m
}
@@ -130,6 +132,10 @@ trait ValidationTFunctions {
def fromEitherT[F[_], E, A](e: EitherT[F, E, A])(implicit F: Functor[F]): ValidationT[F, E, A] =
validationT(F.map(e.run)(Validation.fromEither(_)))
+
+ def validationTMonadWriter[F[_, _], E, W](implicit MW0: MonadWriter[F, W]) = new ValidationTMonadWriter[F, E, W]{
+ implicit def MW = MW0
+ }
}
trait FailProjectionTFunctions {
@@ -156,6 +162,7 @@ trait FailProjectionTFunctions {
}
implicit def FailProjectionTBiIso[F[_]] = new IsoBifunctorTemplate[({type λ[α, β] = FailProjectionT[F, α, β]})#λ, ({type λ[α, β] = ValidationT[F, α, β]})#λ] {
+
def to[E, A](fa: FailProjectionT[F, E, A]): ValidationT[F, E, A] = fa.validationT
def from[E, A](ga: ValidationT[F, E, A]): FailProjectionT[F, E, A] = ga.fail
@@ -291,3 +298,49 @@ trait ValidationTMonadTrans[A] extends MonadTrans[({type λ[α[_], β] = Validat
implicit def apply[M[_] : Monad]: Monad[({type λ[α] = ValidationT[M, A, α]})#λ] = ValidationT.validationTMonad[M, A]
}
+
+private[scalaz] trait ValidationTMonadWriter[F[_,_], E, W] extends MonadWriter[({type f[w, a] = ValidationT[({type m[b] = F[w, b]})#m, E, a]})#f, W] with ValidationTPointed[({type f[x] = F[W, x]})#f, E] with ValidationTMonadTrans[E] {
+ implicit def MW: MonadWriter[F, W]
+ implicit def F: Monad[({type f[x] = F[W, x]})#f] = MW
+ implicit def W: Monoid[W] = MW.W
+
+ override def map[A, B](fa: ValidationT[({type f[x] = F[W, x]})#f, E, A])(f: A => B): ValidationT[({type f[x] = F[W, x]})#f, E, B] =
+ fa map f
+
+ def bind[A, B](fa: ValidationT[({type f[x] = F[W, x]})#f, E, A])(f: A => ValidationT[({type f[x] = F[W, x]})#f, E, B]): ValidationT[({type f[x] = F[W, x]})#f, E, B] = {
+ val tmp = MW.bind[Validation[E, A], Validation[E, B]](fa.run){
+ case Failure(e) => MW.point(Failure(e))
+ case Success(a) => f(a).run
+ }
+
+ ValidationT[({type f[x] = F[W, x]})#f, E, B](tmp)
+ }
+
+ def writer[A](w: (W, A)): ValidationT[({type f[x] = F[W, x]})#f, E, A] =
+ liftM[({type f[x] = F[W, x]})#f, A](MW.writer(w))
+
+ def tell(w: W): ValidationT[({type f[x] = F[W, x]})#f, E, Unit] =
+ liftM[({type f[x] = F[W, x]})#f, Unit](MW.tell(w))
+
+ def listen[A](fa: ValidationT[({type f[x] = F[W, x]})#f, E, A]): ValidationT[({type f[x] = F[W, x]})#f, E, (A, W)] = {
+ val tmp = MW.bind[(Validation[E, A], W), Validation[E, (A, W)]](MW.listen(fa.run)){
+ case (Failure(e), _) => MW.point(Failure(e))
+ case (Success(a), w) => MW.point(Success((a, w)))
+ }
+
+ ValidationT[({type f[x] = F[W, x]})#f, E, (A, W)](tmp)
+ }
+
+ def pass[A](fa: ValidationT[({type f[x] = F[W, x]})#f, E, (A, W => W)]): ValidationT[({type f[x] = F[W, x]})#f, E, A] = {
+ val tmp = MW.bind[Validation[E, ((A, W => W), W)], Validation[E, A]](listen(fa).run){
+ case Failure(e) => MW.point(Failure(e))
+ case Success(((a, f), w)) => MW.map(MW.writer((f(w), a)))(x => Success[E, A](x))
+ }
+
+ ValidationT[({type f[x] = F[W, x]})#f, E, A](tmp)
+ }
+
+ def failureT[A](e: => E): ValidationT[({type m[x] = F[W, x]})#m, E, A] = ValidationT.failureT[({type m[x] = F[W, x]})#m, E, A](e)
+
+ def successT[A](v: => A): ValidationT[({type m[x] = F[W, x]})#m, E, A] = point[A](v)
+}
View
58 core/src/main/scala/scalaz/WriterT.scala
@@ -100,73 +100,73 @@ object WriterT extends WriterTFunctions with WriterTInstances {
writerT(v)
}
-trait WriterTInstances13 {
+trait WriterTInstances14 {
implicit def writerFunctor[W]: WriterTFunctor[Id, W] = new WriterTFunctor[Id, W] {
implicit def F = idInstance
}
}
-trait WriterTInstances12 extends WriterTInstances13 {
+trait WriterTInstances13 extends WriterTInstances14 {
implicit def writerTFunctor[F[+_], W](implicit F0: Functor[F]) = new WriterTFunctor[F, W] {
implicit def F = F0
}
}
-trait WriterTInstances11 extends WriterTInstances12 {
+trait WriterTInstances12 extends WriterTInstances13 {
implicit def writerPointed[W](implicit W0: Monoid[W]): Pointed[({type λ[+α]=Writer[W, α]})#λ] = new WriterTPointed[Id, W] {
implicit def F = idInstance
implicit def W = W0
}
}
-trait WriterTInstances10 extends WriterTInstances11 {
+trait WriterTInstances11 extends WriterTInstances12 {
implicit def writerTPointed[F[+_], W](implicit W0: Monoid[W], F0: Pointed[F]): Pointed[({type λ[+α]=WriterT[F, W, α]})#λ] = new WriterTPointed[F, W] {
implicit def F = F0
implicit def W = W0
}
}
-trait WriterTInstances9 extends WriterTInstances10 {
+trait WriterTInstances10 extends WriterTInstances11 {
implicit def writerApply[W](implicit W0: Semigroup[W]) = new WriterTApply[Id, W] {
implicit def F = idInstance
implicit def W = W0
}
}
-trait WriterTInstances8 extends WriterTInstances9 {
+trait WriterTInstances9 extends WriterTInstances10 {
implicit def writerTApply[F[+_], W](implicit W0: Semigroup[W], F0: Apply[F]) = new WriterTApply[F, W] {
implicit def F = F0
implicit def W = W0
}
}
-trait WriterTInstances7 extends WriterTInstances8 {
+trait WriterTInstances8 extends WriterTInstances9 {
implicit def writerApplicative[W](implicit W0: Monoid[W]) = new WriterTApplicative[Id, W] {
implicit def F = idInstance
implicit def W = W0
}
}
-trait WriterTInstances6 extends WriterTInstances7 {
+trait WriterTInstances7 extends WriterTInstances8 {
implicit def writerTApplicative[F[+_], W](implicit W0: Monoid[W], F0: Applicative[F]) = new WriterTApplicative[F, W] {
implicit def F = F0
implicit def W = W0
}
}
-trait WriterTInstances5 extends WriterTInstances6 {
+trait WriterTInstances6 extends WriterTInstances7 {
implicit def writerMonad[W](implicit W0: Monoid[W]) = new WriterTMonad[Id, W] {
implicit def F = idInstance
implicit def W = W0
}
}
-trait WriterTInstance4 extends WriterTInstances5 {
+trait WriterTInstance5 extends WriterTInstances6 {
implicit def writerTMonad[F[+_], W](implicit W0: Monoid[W], F0: Monad[F]) = new WriterTMonad[F, W] {
implicit def F = F0
implicit def W = W0
}
}
-trait WriterTInstances3 extends WriterTInstance4 {
+trait WriterTInstances4 extends WriterTInstance5 {
implicit def writerBifunctor = new WriterTBifunctor[Id] {
implicit def F = idInstance
}
@@ -179,7 +179,7 @@ trait WriterTInstances3 extends WriterTInstance4 {
implicit def writerEqual[W, A](implicit E: Equal[(W, A)]) = E.contramap((_: Writer[W, A]).run)
}
-trait WriterTInstances2 extends WriterTInstances3 {
+trait WriterTInstances3 extends WriterTInstances4 {
implicit def writerTBifunctor[F[+_]](implicit F0: Functor[F]) = new WriterTBifunctor[F] {
implicit def F = F0
}
@@ -192,13 +192,13 @@ trait WriterTInstances2 extends WriterTInstances3 {
implicit def writerTEqual[F[+_], W, A](implicit E: Equal[F[(W, A)]]) = E.contramap((_: WriterT[F, W, A]).run)
}
-trait WriterTInstances1 extends WriterTInstances2 {
+trait WriterTInstances2 extends WriterTInstances3 {
implicit def writerComonad[W] = new WriterComonad[W] {
implicit def F = implicitly
}
}
-trait WriterTInstances0 extends WriterTInstances1 {
+trait WriterTInstances1 extends WriterTInstances2 {
implicit def writerBitraverse: WriterTBitraverse[Id] = new WriterTBitraverse[Id] {
implicit def F = idInstance
}
@@ -208,9 +208,13 @@ trait WriterTInstances0 extends WriterTInstances1 {
implicit def writerEach[W]: WriterTEach[Id, W] = new WriterTEach[Id, W] {
implicit def F = idInstance
}
+ implicit def writerMonadWriter[W](W0: Monoid[W]) = new WriterMonadWriter[Id, W] {
+ implicit def F = idInstance
+ implicit def W = W0
+ }
}
-trait WriterTInstances extends WriterTInstances0 {
+trait WriterTInstances0 extends WriterTInstances1 {
implicit def writerTBitraverse[F[+_]](implicit F0: Traverse[F]) = new WriterTBitraverse[F] {
implicit def F = F0
}
@@ -224,6 +228,13 @@ trait WriterTInstances extends WriterTInstances0 {
}
}
+trait WriterTInstances extends WriterTInstances0 {
+ implicit def writerTMonadWriter[F[+_], W](implicit F0: Monad[F], W0: Monoid[W]) = new WriterMonadWriter[F, W] {
+ implicit def F = F0
+ implicit def W = W0
+ }
+}
+
trait WriterTFunctions {
def writerT[F[+_], W, A](v: F[(W, A)]): WriterT[F, W, A] = new WriterT[F, W, A] {
val run = v
@@ -342,3 +353,20 @@ trait WriterComonad[W] extends Comonad[({type λ[+α] = Writer[W, α]})#λ] with
override def cobind[A, B](fa: Writer[W, A])(f: (Writer[W, A]) => B): Writer[W, B] =
Writer(fa.written, f(fa))
}
+
+private[scalaz] trait WriterMonadWriter[F[+_], W] extends MonadWriter[({type f[+w, +a] = WriterT[F, w, a]})#f, W] with WriterTPointed[F, W] {
+ implicit def F: Monad[F]
+ implicit def W: Monoid[W]
+
+ def bind[A, B](fa: WriterT[F, W, A])(f: A => WriterT[F, W, B]): WriterT[F, W, B] = fa flatMap f
+
+ def writer[A](v: (W, A)): WriterT[F, W, A] = WriterT.writerT(F.point(v))
+
+ def tell(w: W): WriterT[F, W, Unit] = writer((w, ()))
+
+ def listen[A](fa: WriterT[F, W, A]): WriterT[F, W, (A, W)] =
+ WriterT(F.bind(fa.run){ case (w, a) => F.point((w, (a, w))) })
+
+ def pass[A](fa: WriterT[F, W, (A, W => W)]): WriterT[F, W, A] =
+ WriterT(F.bind(fa.run){ case (w, (a, f)) => F.point((f(w), a)) })
+}
View
2  tests/src/test/scala/scalaz/ValidationTTest.scala
@@ -32,4 +32,4 @@ class ValidationTTest extends Spec {
def foldable[F[_] : Traverse, E] = Foldable[({type λ[α] = ValidationT[F, E, α]})#λ]
}
-}
+}
Something went wrong with that request. Please try again.