Skip to content

Instantly share code, notes, and snippets.

@Mortimerp9
Last active December 16, 2015 04:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mortimerp9/5378757 to your computer and use it in GitHub Desktop.
Save Mortimerp9/5378757 to your computer and use it in GitHub Desktop.
Sample code for the following post https://coderwall.com/p/pdrz7q
object test {
//the companion object, with functions to help in creating readers
object Reader {
implicit def reader[C, R](block: C => R) = Reader[C, R](block)
def pure[From, To](a: To) = Reader((c: From) => a)
}
//the actual reader object, wrapping a function
case class Reader[From, +To](wrappedF: From => To) {
def apply(c: From) = wrappedF(c)
def map[Tob](transformF: To => Tob): Reader[From, Tob] =
Reader(c => transformF(wrappedF(c)))
def flatMap[Tob](transformF: To => Reader[From, Tob]): Reader[From, Tob] =
Reader(c => transformF(wrappedF(c))(c))
}
//some test bootstrapping
//Model:
case class User(val id: Long)
case class Post(val title: String)
//Connections:
trait UserConnection {
def readUser(id: Long): Option[User] = Some(User(id))
}
trait PostConnection {
def readPosts(user: User): Seq[Post] = Seq(Post("test"), Post("test2"))
}
//shortcut to the combined type
type UserPostConn = UserConnection with PostConnection
//trying the reader
import Reader._
//a concrete implementation of the two connections
class RealConn extends UserConnection with PostConnection {}
val conn = new RealConn
/**
* get a list of posts for a specific user
*/
def userPosts(userID: Long): Reader[UserPostConn, Seq[Post]] = reader { conn =>
(conn.readUser(userID) map { user =>
conn.readPosts(user)
}) getOrElse (List()) //getting rid of the Option just to simplify the code in this article
}
/**
* just the titles please
*/
def titles(id: Long) = userPosts(id).map { postIterable =>
postIterable.map(_.title)
}
//try covariance
val tr: Reader[UserPostConn, Iterable[Post]] = userPosts(10l)
tr(conn)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment