Skip to content

Instantly share code, notes, and snippets.

@ahoy-jon
Last active August 29, 2015 14:05
Show Gist options
  • Save ahoy-jon/b8c44bf4ec32eac2fe23 to your computer and use it in GitHub Desktop.
Save ahoy-jon/b8c44bf4ec32eac2fe23 to your computer and use it in GitHub Desktop.
object Reader {
def map2[I, O, O1, O2](r1: Reader[I, O1], r2: Reader[I, O2])(f: (O1, O2) => O): Reader[I, O] = Reader { s: I =>
(r1.p(s), r2.p(s)) match {
case (Success(s1), Success(s2)) => Success(f(s1, s2))
case (Success(_), Failure(e)) => Failure(e)
case (Failure(e), Success(_)) => Failure(e)
case (Failure(e1), Failure(e2)) => Failure(e1 ++ e2)
}
}
trait RM[I] {type M[A] = Reader[I,A]}
//trait DonRM {
// type MI
// type M[A] = Reader[MI, A]
//}
//implicit def readerIsAFunctor[I]: Functor[(DonRM {type MI = I})#M] = new Functor[(DonRM {type MI = I})#M] {
// override def fmap[A, B](m: Reader[I, A], f: (A) => B) = m.map(f)
//}
implicit def readerIsAFunctor[I]: Functor[RM[I]#M] = new Functor[RM[I]#M] {
override def fmap[A, B](m: Reader[I, A], f: (A) => B) = m.map(f)
}
implicit def readerIsAnApplicative[I]: Applicative[RM[I]#M] = new Applicative[RM[I]#M] {
override def pure[A](a: A) = Reader { _ => Success(a) }
override def apply[A, B](mf: Reader[I, A => B], ma: Reader[I, A]) = map2(mf, ma)((f, a) => f(a))
override def map[A, B](m: Reader[I, A], f: (A) => B) = m.map(f)
}
import scala.language.implicitConversions
// Here we help the compiler a bit. Thanks @skaalf (Julien Tournay) and https://github.com/jto/validation for the trick
implicit def fcbReads[I]: FunctionalCanBuild[RM[I]#M] = functionalCanBuildApplicative[RM[I]#M]
implicit def fboReads[I, A](a: Reader[I, A])(implicit fcb: FunctionalCanBuild[({type λ[x] = Reader[I, x]})#λ]) = new FunctionalBuilderOps[({type λ[x] = Reader[I, x]})#λ, A](a)(fcb)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment