Last active
December 16, 2015 04:39
-
-
Save Mortimerp9/5378757 to your computer and use it in GitHub Desktop.
Sample code for the following post https://coderwall.com/p/pdrz7q
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
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