Skip to content

Instantly share code, notes, and snippets.

@folone
Created October 18, 2012 12:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save folone/3911559 to your computer and use it in GitHub Desktop.
Save folone/3911559 to your computer and use it in GitHub Desktop.
Reader exercise (inspired by gist from @tonymorris: https://gist.github.com/3884189)
case class Reader[T, +A](run: T ⇒ A) {
def map[B](f: A ⇒ B): Reader[T, B] =
Reader((r: T) ⇒ f(run(r)))
def flatMap[B](f: A ⇒ Reader[T, B]): Reader[T, B] =
Reader((r: T) ⇒ f(run(r)).run(r))
def &&&[B](x: Reader[T, B]): Reader[T, (A, B)] =
for {
a ← this
b ← x
} yield (a, b)
}
object Reader {
def point[T, A](a: A): Reader[T, A] = Reader(_ ⇒ a)
def sequence[T, A](t: List[Reader[T, A]]): Reader[T, List[A]] =
t.foldLeft(point[T, List[A]](Nil: List[A])) { (acc, v) ⇒
for {
x ← v
xs ← acc
} yield x::xs
}
def filterM[T, A](p: A ⇒ Reader[T, Boolean], a: List[A]): Reader[T, List[A]] =
a match {
case x::xs ⇒ for {
flg ← p(x)
ys ← filterM(p, xs)
} yield if(flg) x::ys else ys
case Nil ⇒ point(Nil)
}
def fill[T, A](n: Int)(t: Reader[T, A]): Reader[T, List[A]] =
t.map(a ⇒ List.fill(n)(a))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment