Skip to content

Instantly share code, notes, and snippets.

@JoolsF
Last active February 4, 2019 10:35
Show Gist options
  • Save JoolsF/bbd5ac382a484bc99590a2cb0e5a674a to your computer and use it in GitHub Desktop.
Save JoolsF/bbd5ac382a484bc99590a2cb0e5a674a to your computer and use it in GitHub Desktop.
Reader Monad example 1
/**
*
* The classic use of Readers is to build programs that accept a configuration as a
* parameter. Let’s ground this with a complete example of a simple login system.
* Our configuration will consist of two databases: a list of valid users and a
* list of their passwords:
*/
case class Db(usernames: Map[Int, String],
passwords: Map[String, String]
)
type DbReader[A] = Reader[Db, A]
def findUsername(userId: Int): DbReader[Option[String]] = Reader(_.usernames.get(userId))
def checkPassword(username: String,
password: String): DbReader[Boolean] =
Reader(_.passwords.get(username).contains(password))
import cats.syntax.applicative._ // for pure
def checkLogin(userId: Int,
password: String): DbReader[Boolean] =
for {
maybeUsername <- findUsername(userId)
passwordOk <- maybeUsername match {
case Some(u) => checkPassword(u, password)
case None => false.pure[DbReader]
}
} yield passwordOk
val users = Map(
1 -> "dade",
2 -> "kate",
3 -> "margo"
)
val passwords = Map(
"dade" -> "zerocool",
"kate" -> "acidburn",
"margo" -> "secret"
)
val db = Db(users, passwords)
checkLogin(1, "zerocool").run(db)
// res10: cats.Id[Boolean] = true
checkLogin(4, "davinci").run(db)
// res11: cats.Id[Boolean] = false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment