Skip to content

Instantly share code, notes, and snippets.

@purefn
Last active October 27, 2015 19:43
Show Gist options
  • Save purefn/610a5b02f2221eec0877 to your computer and use it in GitHub Desktop.
Save purefn/610a5b02f2221eec0877 to your computer and use it in GitHub Desktop.
import scalaz._
import scalaz.stream._
import scodec.bits._
type EntityBody[F] = Process[Free.FreeC[F, ?], ByteVector]
final case class Request[A]
( method: Method
, uri: Uri
, httpVersion: HttpVersion
, headers: CI[String] ==>> IList[String]
, body: A
)
final case class Response[A]
( status: Status
, httpVersion: HttpVersion
, headers: CI[String] ==>> IList[String]
, body: A
)
sealed trait HttpcOps[A]
object HttpcOps {
final case class Send[F[_]]( req: Request[EntityBody[F]]) extends HttpcOps[Response[EntityBody[F]]]
}
sealed abstract class Httpc[F[_]](inj: HttpcOps ~> F) {
final def send(req: Request[EntityBody[F]]): Free.FreeC[F, Response[EntityBody[F]]] =
Free.liftFC(inj(HttpcOps.Send(req)))
}
import scalaz._
import scalaz.concurrent._
import scalaz.stream._
import org.http4s._
object TestHttpcOps {
// HttpcOps interpreters will need to know about the interpreter for the algebras in which they are embedded
// so they can run the effects created while streaming the body
def apply[F[_]](f: => F ~> Task): HttpcOps ~> Task =
new (HttpcOps ~> Task) {
import HttpcOps._
def apply[A](h: HttpcOps[A]) =
h match {
case o: Send[f] =>
val req = o.req
if (req.method == Method.POST && req.uri == Http4s.uri("https://example.com/echo")) {
val reqBody =
req.body.
// run the interpreter, as if we were sending to a real server
translate(new (Free.FreeC[f, ?] ~> Task) {
def apply[A](ff: Free.FreeC[f, A]) = Free.runFC(ff)(f) // <-- compile error, need evidence that F =:= f somehow
})
val respBody =
// since this is just a fake server, we just turn the stream back into an entity body
reqBody.translate(new (Task ~> Free.FreeC[F, ?]) {
def apply[A](a: Task[A]) = ??? ///Free.pure[Coyoneda[F, ?], A](a)
})
Task.delay(Response(Status.Ok, req.httpVersion, IMap(), body))
} else
Task.delay(Response(Status.NotFound, req.httpVersion, IMap(), EntityBody.empty[f]))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment