Skip to content

Instantly share code, notes, and snippets.

@loosechainsaw
Created November 6, 2013 12:16
Show Gist options
  • Save loosechainsaw/7335157 to your computer and use it in GitHub Desktop.
Save loosechainsaw/7335157 to your computer and use it in GitHub Desktop.
Fuck Yeah Reader Monad
package examples.monads
case class User(id: Int, username: String, name: String)
trait UserRepository{
def getById(id: Int) : Option[User]
def save(user: Option[User]) : Unit
}
trait UserService{
def updateName(id: Int, name: String) : Reader[UserServiceConfig, Unit]
def deleteUser(id: Int) : Reader[UserServiceConfig, Unit]
}
trait UserServiceConfig{
def Repository : UserRepository
}
sealed case class Reader[Environment,+Result](function: Environment => Result){
def result(environment: Environment) : Result = function(environment)
def map[T](f: Result => T) : Reader[Environment, T] =
new Reader[Environment,T](Env => {
val prior = result(Env)
f(prior)
})
def flatMap[T](f: Result => Reader[Environment,T]) : Reader[Environment,T] =
new Reader[Environment,T](Env => {
val prior = result(Env)
f(prior).result(Env)
})
}
object ReaderMonadExamples {
def run(){
val service = new UserService(){
def updateName(id: Int, name: String) : Reader[UserServiceConfig, Unit] = {
new Reader(config => {
val repo = config.Repository
val updatedUser = repo.getById(id).map( x => x.copy(x.id,x.username,name) )
repo.save(updatedUser)
})
}
def deleteUser(id: Int) : Reader[UserServiceConfig, Unit] = {
new Reader(config => {
val repo = config.Repository
val user = repo.getById(id)
user.foreach(f => println("Deleting: " + f.toString))
})
}
}
val configuration = new UserServiceConfig(){
def Repository = new UserRepository(){
def getById(id: Int) : Option[User] = {
id match{
case 1 => Some(User(1,"Tom", "Tom"))
case _ => None
}
}
def save(user: Option[User]) : Unit = {
user match{
case None => println("Nothing")
case Some(x) => println("Saving: " + x)
}
}
}
}
val reader = service.updateName(1, "Blair")
.flatMap(x => service.deleteUser(1))
.result(configuration)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment