Skip to content

Instantly share code, notes, and snippets.

@animatedlew
Last active September 10, 2017 04:05
Show Gist options
  • Save animatedlew/f3ef59e1ee16acfd54ea3eb5c2df2ebc to your computer and use it in GitHub Desktop.
Save animatedlew/f3ef59e1ee16acfd54ea3eb5c2df2ebc to your computer and use it in GitHub Desktop.
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