Skip to content

Instantly share code, notes, and snippets.

View tomaszperek's full-sized avatar

Tomasz Perek tomaszperek

View GitHub Profile
@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 / 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 / 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 :: _))
}
@tomaszperek
tomaszperek / IsHNilHListOfM.scala
Created October 19, 2015 21:37
implicit evidence for HNil
implicit def IsHNilHListOfM[M[_]](implicit m: Monad[M]) = new IsHListOfM[M, HNil, HNil] {
override def hsequence(l: HNil): M[HNil] = m.pure(HNil)
}
@tomaszperek
tomaszperek / IsHListOfM.scala
Created October 19, 2015 21:36
Evidence trait to prove that HList consists of Monads
trait IsHListOfM[M[_], In <: HList, Out <: HList] extends ToMonadOps{
def hsequence(l: In): M[Out]
}