Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- object ReaderMonad {
- class Reader[-E, +R] private (g: E => R) {
- def apply(env: E): R = g(env)
- def map[A](f: R => A): Reader[E, A] = new Reader[E, A](env => f(g(env)))
- def flatMap[A, B <: E](f: R => Reader[B, A]): Reader[B, A] = new Reader[B, A](env => f(g(env))(env))
- }
- def pure[E, R](v: R): Reader[E, R] = Reader.pure(v)
- def ask[E]: Reader[E, E] = Reader.ask
- private[this] object Reader {
- def pure[E, R](v: R): Reader[E, R] = new Reader[E, R](_ => v)
- def ask[E]: Reader[E, E] = new Reader[E, E](identity)
- }
- }
- object Main {
- import ReaderMonad._
- case class User(id: Int)
- trait UserRepository {
- def find(id: Int): Option[User]
- }
- object UserRepository extends UserRepository {
- private[this] val users = Map(1 -> User(1))
- def find(id: Int): Option[User] = users.get(id)
- }
- sealed trait AuthResult
- case class Success(user: User) extends AuthResult
- case class Failure(message: String) extends AuthResult
- case class Authenticator(repository: UserRepository) {
- def authenticate(username: String, password: String): Reader[Int, AuthResult] = for {
- userId <- ask
- } yield {
- if (isValid(username, password)) {
- repository find(userId) map (Success(_)) getOrElse Failure("The user doesn't exist.")
- } else {
- Failure("Incorrect username or password.")
- }
- }
- def isValid(username: String, password: String): Boolean = true
- }
- def main(args: Array[String]): Unit = {
- val authenticator = new Authenticator(UserRepository)
- val readerForUser1 = authenticator.authenticate("hoge", "")
- val readerForUser2 = authenticator.authenticate("fuba", "")
- println(readerForUser1(1))
- println(readerForUser2(2))
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement