Skip to content

Instantly share code, notes, and snippets.

@arturaz
Created December 17, 2018 07:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arturaz/e1877e30a06b40baa259b2bf3c604921 to your computer and use it in GitHub Desktop.
Save arturaz/e1877e30a06b40baa259b2bf3c604921 to your computer and use it in GitHub Desktop.
package app
import shapeless.ops.hlist.Mapper
import shapeless.{::, HList, HNil, Poly2}
case class Params()
sealed trait EvaluatableGeneratorFilter[+Result] {
def eval(p: Params): Result
}
case class FilteredValue[A, Filters <: HList, Outputs <: HList](
filters: Filters
)(private val f: Outputs => A)(
implicit
mapper: Mapper.Aux[FilteredValue.evalPoly.type, Filters, Outputs]
) {
def eval(p: Params): A = {
val mapped = filters.map(FilteredValue.evalPoly)
f(mapped)
}
def map[B](
// Needs to have different name than mapper, otherwise implicit resolution fails...
resultMapper: A => B
): FilteredValue[B, Filters, Outputs] =
FilteredValue[B, Filters, Outputs](filters) { a =>
resultMapper(f(a))
}
}
object FilteredValue {
object evalPoly extends Poly2 {
implicit def `case`[T]: Case.Aux[EvaluatableGeneratorFilter[T], Params, T] = at(_.eval(_))
}
def constant[A](a: A): FilteredValue[A, HNil, HNil] = FilteredValue(HNil: HNil) { _ => a }
}
object Test {
val test =
new EvaluatableGeneratorFilter[Int] { def eval(p: Params) = 3 } ::
new EvaluatableGeneratorFilter[String] { def eval(p: Params) = "3" } :: HNil
val res = FilteredValue(test)((_ : (Int :: String :: HNil)) => 3).eval(Params())
}
[error] D:\work\scala\shapeless-guide\src\main\scala\app\Main.scala:44:32: could not find implicit value for parameter mapper: shapeless.ops.hlist.Mapper.Aux[app.FilteredValue.evalPoly.type,app.EvaluatableGeneratorFilter[Int] :: app.EvaluatableGeneratorFilter[String] :: shapeless.HNil,Int :: String :: shapeless.HNil]
[error] val res = FilteredValue(test)((_ : (Int :: String :: HNil)) => 3).eval(Params())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment