Skip to content

Instantly share code, notes, and snippets.

View tomaszperek's full-sized avatar

Tomasz Perek tomaszperek

View GitHub Profile
@tomaszperek
tomaszperek / zip3.scala
Created October 10, 2015 11:21
Zip3 helper
def zip3[A, B, C](fA: Future[A], fB: Future[B], fc: Future[C]): Future[(A, B, C)] =
(fA zip fB zip fC) map { case ((a, b), c) => (a, b, c)}
@tomaszperek
tomaszperek / SimpleDirective.scala
Created October 10, 2015 11:28
Naive quasispray directive
trait Directive[X <: HList] { self =>
def happly(f: X => Route): Route
def apply[F](f: F)(implicit fp: FnToProduct.Aux[F, X => Route]) = {
happly(fp(f))
}
def &[Y <: HList](that: Directive[Y])(implicit prepend: Prepend[X, Y]): Directive[prepend.Out] = new Directive[prepend.Out] {
override def happly(f: prepend.Out => Route): Route = {
self.happly( x =>
that.happly( y =>
f(prepend(x, y))
@tomaszperek
tomaszperek / ScalacApplicativeBuilder.scala
Last active October 21, 2015 19:37
Implementation of ScalacApplicativeBuilder
case class ScalacApplicativeBuilder[M[_], In <: HList, Out <: HList](values: In)(implicit m: Monad[M]) {
def asTuple[T](implicit ev: IsHListOfM[M, In, Out], m: Monad[M], tupler: Tupler.Aux[Out, T]): M[T] = m.map(hsequence(values))(_.tupled)
def apply[F, FOut](f: F)(implicit fnEv: FnToProduct.Aux[F, Out => FOut], ev: IsHListOfM[M, In, Out]): M[FOut] =
m.map(hsequence(values))(fnEv(f))
def :@:[X, T1](newOne: M[X]) = ScalacApplicativeBuilder[M, M[X] :: In, X :: Out](newOne :: values)
}
@tomaszperek
tomaszperek / ScalacApplicativeBuilderSpecs.scala
Created October 19, 2015 21:59
Specs demonstrating ScalacApplicativeBuilder
class ScalacApplicativeBuilderSpecs extends FlatSpec with Matchers with ScalaFutures {
import scala.concurrent.ExecutionContext.Implicits.global
import scalaz.Scalaz._
"ScalacApplicativeBuilder" should "work" in {
val optionsAB = Option(1) :@: Option(2)
optionsAB((_: Int) + (_: Int)) should equal(Some(3))
(Future(1) :@: Future(2) :@: Future("3")) { (a: Int, b: Int, c: String) =>
@tomaszperek
tomaszperek / ScalacApplicativeBuilder.scala
Last active October 19, 2015 21:57
Full implementation of ScalacApplicativeBuilder
package io.scalac
import shapeless._
import shapeless.ops.function.FnToProduct
import shapeless.ops.hlist.Tupler
import scala.languageFeature.implicitConversions
import scalaz.Monad
import scalaz.syntax.ToMonadOps
package object shapelessmonad {
@tomaszperek
tomaszperek / ToScalacApplicativeBuilder.scala
Created October 19, 2015 21:53
Converting Monads to ScalacApplicativeBuilder
implicit def toScalacApplicativeBuilder[M[_], V](value: M[V])(implicit ev: IsHListOfM[M, M[V] :: HNil, V :: HNil], m: Monad[M]): ScalacApplicativeBuilder[M, M[V] :: HNil, V::HNil] =
new ScalacApplicativeBuilder[M, M[V] :: HNil, V :: HNil](value :: HNil)
@tomaszperek
tomaszperek / ZipSpec.scala
Created October 19, 2015 21:47
How zip works with Monads
class ZipSpec extends FlatSpec with ScalaFutures with Matchers {
import scala.concurrent.ExecutionContext.Implicits.global
import scalaz.Scalaz._
"zip" should "provide one future from args of futures" in {
val result = zip(successful(1), successful(true), successful("string"), successful(1.0))
val (a, b, c, d) = result.futureValue
(a, b, c, d) should equal((1, true, "string", 1.0))
}
@tomaszperek
tomaszperek / hsequence_and_zip.scala
Created October 19, 2015 21:46
Implementation of hsequence and zip for Monads
def hsequence[M[_], In <: HList, Out <: HList](l: In)(implicit ev: IsHListOfM[M, In, Out], m: Monad[M]) = ev.hsequence(l)
def zip[M[_], P <: Product, In <: HList, Out <: HList]
(p: P)
(implicit gen: Generic.Aux[P, In], ev: IsHListOfM[M, In, Out], tupler: Tupler[Out], m: Monad[M]) = {
m.map(hsequence(gen.to(p)))(_.tupled)
}
@tomaszperek
tomaszperek / IsHListOfM.scala
Created October 19, 2015 21:45
Implementation of IsHListOfM object
object IsHListOfM {
def apply[M[_], In <: HList, Out <: HList](implicit isHM: IsHListOfM[M, In, Out], m: Monad[M]): IsHListOfM[M, In, Out] = isHM
implicit def IsHNilHListOfM[M[_]](implicit m: Monad[M]) = new IsHListOfM[M, HNil, HNil] {
override def hsequence(l: HNil): M[HNil] = m.pure(HNil)
}
implicit def hconsIsHListOfM[M[_], H, In <: HList, Out <: HList](implicit ev: IsHListOfM[M, In, Out], m: Monad[M]): IsHListOfM[M, M[H] :: In, H :: Out] = new IsHListOfM[M, M[H] :: In, H :: Out] {
override def hsequence(l: M[H] :: In): M[H :: Out] =
l.head.flatMap(h => ev.hsequence(l.tail).map(h :: _))
@tomaszperek
tomaszperek / hconsIsHListOfM.scala
Created October 19, 2015 21:43
Evidence for longer HLists
implicit def hconsIsHListOfM[M[_], H, In <: HList, Out <: HList](
implicit ev: IsHListOfM[M, In, Out], m: Monad[M]
): IsHListOfM[M, M[H] :: In, H :: Out] = new IsHListOfM[M, M[H] :: In, H :: Out] {
override def hsequence(l: M[H] :: In): M[H :: Out] =
l.head.flatMap(h => ev.hsequence(l.tail).map(h :: _))
}