Skip to content

Instantly share code, notes, and snippets.

@sarahgerweck
Forked from travisbrown/unwrap.scala
Last active August 29, 2015 14:06
Show Gist options
  • Save sarahgerweck/4ccf7d154c6edfa6917a to your computer and use it in GitHub Desktop.
Save sarahgerweck/4ccf7d154c6edfa6917a to your computer and use it in GitHub Desktop.
scalaVersion := "2.11.2"
libraryDependencies += "com.chuusai" %% "shapeless" % "2.0.0"
name := "Observe Sample"
trait Obs[A, B] { def value: A }
trait ChildObs[A, B] extends Obs[A, B]
object Obs {
import shapeless._, poly._, ops.hlist.Mapper, ops.function.FnToProduct
object values extends Poly1 {
implicit def a1[A, X, C <: Obs[A,X]] = at[C]{ _.value }
implicit def a2[A, X] = at[Obs[A,X]]{ _.value }
implicit def a3[A, C <: Obs[A, _]] = at[C]{ _.value }
}
def calculate[T, V <: HList, L <: HList, F, Z](obss: T)(f: F)(implicit
gen: Generic.Aux[T, L],
mapper: Mapper.Aux[values.type, L, V],
ftp: FnToProduct.Aux[F, V => Z]
): Z = ftp(f)(mapper.apply(gen.to(obss)))
}
object ObsExample {
import Obs._
val obs1: Obs[Double, Double] = new ChildObs[Double, Double] { val value = 10.0 }
val obs2: ChildObs[Option[Int], Int] = new ChildObs[Option[Int], Int] { val value = Some(1) }
def func(d: Double, i: Option[Int]) = d + i.getOrElse(0).toDouble
println(calculate(obs1, obs2)(func _))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment