Created
March 12, 2012 01:23
-
-
Save mads-hartmann/2019152 to your computer and use it in GitHub Desktop.
monad transformers confusion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sidewayscoding | |
import scalaz._ | |
import Scalaz._ | |
import scalaz.EitherT._ | |
import scalaz.StateT._ | |
import scala.collection.immutable.{ HashMap } | |
object PhonebookMonadTransformerApp extends App { | |
import PhonebookData._ | |
type St = (Int, Map[String, String]) | |
type Failure = String | |
// We want some state | |
type PhonebookStateT[A] = StateT[Id, St, A] | |
// We want some error handling | |
type PhonebookT[A] = EitherT[PhonebookStateT, Failure, A] | |
def execute(cmd: Command): PhonebookT[String] = liftStateTtoEitherT(cmd match { | |
case Lookup(name) => for { | |
s <- tick() | |
(cnt, book) = s | |
rslt = book.get(name).map( x => Right("information for mads: " + x) ) | |
.getOrElse(Left("Failure executing command %d: Not Found in phonebook".format(cnt))) | |
} yield rslt | |
case Remove(name) => for { | |
_ <- tick() | |
rslt <- modify { (s: St) => (s._1, s._2 - name)} | |
} yield Right("Successfully removed %s to the book".format(name)) | |
case Add(name, information) => for { | |
s <- tick() | |
rslt <- modify { (s: St) => (s._1, s._2 + (name -> information)) } | |
} yield Right("Successfully added %s to the book".format(name)) | |
}) | |
def tick(): PhonebookStateT[St] = for { | |
s <- init[St] | |
(cnt, storage) = s | |
newS <- put( (cnt+1, storage)) | |
} yield newS | |
// Can I get rid of the need for this somehow? | |
def liftStateTtoEitherT[A](st: PhonebookStateT[Either[Failure, A]]): PhonebookT[A] = | |
EitherT[PhonebookStateT, Failure, A](st) | |
// | |
// Example | |
// | |
val initial = (0, HashMap[String, String]()) | |
val rslt1 = for { | |
msg1 <- execute(Add("mads","21")) | |
msg2 <- execute(Lookup("mads")) | |
} yield List(msg1, msg2).mkString("\n") | |
println("rslt1:\n" + rslt1.run.eval(initial)) | |
val rslt2 = for { | |
msg1 <- execute(Lookup("mads")) | |
msg2 <- execute(Add("mads","21")) | |
} yield List(msg1, msg2).mkString("\n") | |
println("rslt2:\n" + rslt2.run.eval(initial)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment