Skip to content

Instantly share code, notes, and snippets.

@noelwelsh
Created July 26, 2016 15:02
Show Gist options
  • Save noelwelsh/0fd114f222f5fdbd0380fc07b6a2d840 to your computer and use it in GitHub Desktop.
Save noelwelsh/0fd114f222f5fdbd0380fc07b6a2d840 to your computer and use it in GitHub Desktop.
Reader monad example
object ReaderExample {
import scalaz.Monad
import scalaz.syntax.monad._
type AccountId = Int
type Account = Int
type BetId = Int
type Bet = Int
final case class Config(
accounts: Map[AccountId, Account],
bets: Map[Account, List[Bet]]
)
type Reader[A,B] = A => B
implicit def monadInstance[Config]: Monad[({type L[B] = Reader[Config,B]})#L] =
new Monad[({type L[B] = Reader[Config,B]})#L] {
override def bind[A, B](fa: Reader[Config,A])(f: (A) ⇒ Reader[Config,B]): Reader[Config,B] =
(config: Config) => {
f(fa(config))(config)
}
override def point[A](a: ⇒ A): Reader[Config,A] =
(config: Config) => a
}
type Configured[A] = Reader[Config,A]
def getAccount(accountId: AccountId): Configured[Account] =
(config: Config) => config.accounts(accountId)
def getBets(account: Account): Configured[List[Bet]] =
(config: Config) => config.bets(account)
def getLastBet(bets: List[Bet]): Bet =
bets.last
val example: AccountId => Reader[Config,Bet] =
(accountId: AccountId) => {
for {
account <- getAccount(accountId)
bets <- getBets(account)
last <- getLastBet(bets).pure[Configured]
} yield last
}
val result =
example(1)(Config(accounts = Map(1 -> 10), bets = Map(10 -> List(1,2,3))))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment