Skip to content

Instantly share code, notes, and snippets.

@arosien
Created December 23, 2011 21:27
Show Gist options
  • Save arosien/1515399 to your computer and use it in GitHub Desktop.
Save arosien/1515399 to your computer and use it in GitHub Desktop.
reader monad with kleisli and tuple/untupling
import scalaz._
import Scalaz._
case class Foo(value: String)
case class Bar(value: String)
case class Baz(foo: Foo, bar: Bar)
type E = Map[String, String]
type K[M[_],A,B] = Kleisli[M,A,B]
def pair[M[_], E, A, B](f: K[M, E, A], g: K[M, E, B])(implicit t: Functor[M], ap: Apply[M]): K[M, E, (A,B)] = kleisli(e => (f(e) |@| g(e)).tupled)
val fooR = (e: E) => e.get("foo").map(Foo(_))
val barR = (e: E) => e.get("bar").map(Bar(_))
def bazR(fooR: E => Option[Foo])(barR: E => Option[Bar]) =
for (fb <- pair(kleisli(fooR), kleisli(barR)))
yield Baz(fb._1, fb._2)
val env: E = Map("foo" -> "oof", "bar" -> "rab")
fooR(env) must beSome(Foo("oof"))
barR(env) must beSome(Bar("rab"))
bazR(fooR)(barR)(env) must beSome(Baz(Foo("oof"), Bar("rab")))
bazR(fooR)(barR)(Map("foo" -> "oof")) must beNone
bazR(fooR)(barR)(Map("bar" -> "rab")) must beNone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment