Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created March 20, 2019 18:21
Show Gist options
  • Save yasuabe/9b2656c16aebdb092b2eb8abf4807b8c to your computer and use it in GitHub Desktop.
Save yasuabe/9b2656c16aebdb092b2eb8abf4807b8c to your computer and use it in GitHub Desktop.
a composed free monads sample of Hammock with Apache HttpComponents Client and monix Task
package qiita_sample1
import cats.{InjectK, ~>}
import cats.effect.{ExitCode, Sync}
import cats.free.Free
import cats.syntax.either._
import iota.TListK.:::
import iota.{CopK, TNilK}
object Console {
sealed trait ConsoleF[A]
case object Read extends ConsoleF[String]
case class Write(msg: String) extends ConsoleF[Unit]
class ConsoleC[F[α] <: CopK[_, α]](implicit I: CopK.Inject[ConsoleF, F]) {
def read: Free[F, String] = Free.inject(Read)
def write(str: String): Free[F, Unit] = Free.inject(Write(str))
}
object ConsoleC {
implicit def ioC[F[α] <: CopK[_, α]](implicit I: CopK.Inject[ConsoleF, F]): ConsoleC[F] = new ConsoleC[F]
}
def trans[F[_]](implicit F: Sync[F]): ConsoleF ~> F = new (ConsoleF ~> F) {
def apply[A](ca: ConsoleF[A]): F[A] = ca match {
case Read => F.delay(scala.io.StdIn.readLine())
case Write(msg) => F.delay(println(msg))
}
}
}
import monix.eval.{ Task, TaskApp }
import hammock.apache.ApacheInterpreter
import hammock.{HttpF, _}
import hammock.marshalling._
import Console._
object ComposedFreeMain extends TaskApp {
type App[A] = CopK[MarshallF ::: HttpF ::: ConsoleF ::: TNilK, A]
implicit def trans[F[_]](implicit S: Sync[F]): App ~> F = CopK.FunctionK.of(
marshallNT[F], ApacheInterpreter[F].trans, Console.trans(S))
implicit val dummyDecoder: Decoder[String] = (a: Entity) => a.toString.asRight
implicit def httpI: InjectK[HttpF, App] = CopK.Inject[HttpF, App]
implicit def marshallI: InjectK[MarshallF, App] = CopK.Inject[MarshallF, App]
def program(implicit
Console: ConsoleC[App],
Marshall: MarshallC[App],
Hammock: HttpRequestC[App]
): Free[App, String] = for {
_ <- Console.write("What's the ID?")
id <- Console.read
response <- Hammock.get(uri"https://jsonplaceholder.typicode.com/users?id=${id.toString}", Map())
parsed <- Marshall.unmarshall[String](response.entity)
} yield parsed
def run(args: List[String]): Task[ExitCode] = for {
entity <- program foldMap trans[Task]
_ <- Task { println(entity) }
} yield ExitCode.Success
}
// ---- build.sbt ----
//name := "hammock_test"
//
//version := "0.1"
//
//scalaVersion := "2.12.8"
//
//val hammockVer = "0.9.0"
//val circeVer = "0.10.0"
//
//scalacOptions ++= Seq(
// "-encoding", "utf8",
// "-Xfatal-warnings",
// "-Ypartial-unification",
// "-deprecation",
// "-unchecked",
// "-language:implicitConversions",
// "-language:higherKinds",
// "-language:existentials",
// "-language:postfixOps"
//)
//libraryDependencies ++= Seq(
// "com.pepegar" %% "hammock-core",
// "com.pepegar" %% "hammock-circe",
// "com.pepegar" %% "hammock-apache-http",
// "com.pepegar" %% "hammock-asynchttpclient",
// "com.pepegar" %% "hammock-akka-http"
//).map(_ % hammockVer) ++ Seq(
// "io.circe" %% "circe-core",
// "io.circe" %% "circe-generic",
// "io.circe" %% "circe-parser"
//).map(_ % circeVer) ++ Seq(
// "io.monix" %% "monix" % "3.0.0-RC2",
// "io.frees" %% "iota-core" % "0.3.10"
//)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment