Skip to content

Instantly share code, notes, and snippets.

@nuttycom
Created September 21, 2011 18:58
Show Gist options
  • Save nuttycom/1232985 to your computer and use it in GitHub Desktop.
Save nuttycom/1232985 to your computer and use it in GitHub Desktop.
A potential higher-kinded HttpService for BlueEyes
import scalaz._
import scalaz.Scalaz._
trait Future[A]
object Future {
def async[A](a: A): Future[A] = error("todo")
}
sealed trait NotServed
case class HttpRequest[A](content: Option[A])
sealed abstract class HttpService[A, B, +M[_]: Functor] { self =>
def service: HttpRequest[A] => M[B] = error("todo")
def map[C](f: B => C): HttpService[A, C, M] = new HttpService[A, C, M] {
override val service = (r: HttpRequest[A]) => self.service(r).map(f)
}
def mmap[N[_]: Functor](f: M[B] => N[B]): HttpService[A, B, N] = new HttpService[A, B, N] {
override val service = (r: HttpRequest[A]) => f(self.service(r))
}
def contramap[C](f: C => A): HttpService[C, B, M] = new HttpService[C, B, M] {
override val service = (r: HttpRequest[C]) => self.service(r.copy(content = r.content.map(f)))
}
def ~ [X[V] <: Validation[NotServed, V]](other: HttpService[A, B, X])(implicit ev: M[B] <:< X[B], f: Functor[X]) = OrService[A, B](self.mmap(ev), other)
}
case class OrService[A, B](services: HttpService[A, B, ({type X[B] = Validation[NotServed, B]})#X]*) extends HttpService[A, B, ({type X[B] = Validation[NotServed, B]})#X]
case class AsyncService[A, B, M[_]: Functor](delegate: HttpService[A, B, M]) extends HttpService[A, Future[B], M] {
override def service: HttpRequest[A] => M[Future[B]] = (r: HttpRequest[A]) => delegate.map(Future.async).service(r)
}
@mlagutko
Copy link

abstract class Service[A, B, R[A], S[B], +M[_]: Functor] { self =>
def service: R[A] => Validation[NotServed, S[B]]

def map[C](f: B => C): HttpService[A, C, R[A], S[B], M] = new HttpService[A, C, R[C], S[M], M] {
override val service = (r: R[A]) => self.service(r).map(f)
}
}

abstract class HttpService[A, B, +M[_]: Functor] extends Service[A, B, HttpRequest[A], ({type λ[α] = B})#λ, M]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment