Last active
September 10, 2017 04:05
-
-
Save animatedlew/f3ef59e1ee16acfd54ea3eb5c2df2ebc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats.syntax.option._ | |
import cats.instances.option._ | |
import cats.data.{Kleisli, Reader, ReaderT} | |
// this is the ADT for sub confs | |
sealed trait Confs | |
case class Sub1(n: String) extends Confs | |
case class Sub2(n: String) extends Confs | |
// this is the actual app class that fires up once everything is loaded | |
case class App(value: String) | |
// This could be any special type that knows how to get conf settings | |
class Conf { | |
def getSub1 = Sub1("42") | |
def getSub2 = Sub2("88") | |
} | |
// sub1k represents a set of composed functions for the sub1 conf | |
val sub1ka = ReaderT[Option, Sub1, String](_.n.some.map(_ + ":a")) | |
val sub1kb = ReaderT[Option, Sub1, String](_.n.some.map(_ + ":b")) | |
val sub1k = for { | |
a <- sub1ka | |
b <- sub1kb | |
} yield s"$a:$b" | |
// sub2k represents a set of composed functions for the sub2 conf | |
val sub2k = ReaderT[Option, Sub2, String](_.n.some) | |
// Conf is a common type that knows how to convert to both sub types | |
// See the parameterized types of sub1k and sub2k | |
val app: ReaderT[Option, Conf, App] = for { | |
s1 <- sub1k.local[Conf](_.getSub1) | |
s2 <- sub2k.local[Conf](_.getSub2) | |
} yield App(s"$s1:$s2") | |
app(new Conf) | |
// ReaderT[Option, Sub2, String] <=== Sub2 is the input and String is the expected [optional] output | |
// ReaderT[Id, Sub2, String] == Reader[Sub2, String] | |
// Take a list of input and jam it ito a function that takes only one | |
import cats.instances.list._ | |
val list = Reader[String, Int](_.toInt).traverse(List("42", "88", "123")) | |
// -- | |
// all of the following align the types on the right | |
val readerK = for { | |
a <- Reader[String, Int](_.toInt).lift[Option] // a function A => B | |
b <- Kleisli[Option, String, Int](_.toInt.some) // a function A => F[B] | |
c <- Kleisli.pure[Option, String, Int](42) // only have a B | |
d <- Kleisli.lift(Option(42)) // already have an F[B] | |
} yield (a, b, c, d) | |
readerK("42") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment