Created
October 30, 2015 14:23
-
-
Save knutwalker/da7da4262d1fc15a1ec4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import shapeless._ | |
import shapeless.tag._ | |
import shapeless.labelled._ | |
import scala.annotation.implicitNotFound | |
object Pluck { | |
trait FindByName[L <: HList, K] extends DepFn1[L] { | |
type Out | |
} | |
object FindByName { | |
@implicitNotFound("${A} does not have a field ${K}.") | |
type PrettyAux[A, L <: HList, K, Out0] = FindByName[L, K] { type Out = Out0 } | |
type Aux[L <: HList, K, Out0] = FindByName[L, K] { type Out = Out0 } | |
def apply[L <: HList, K](implicit fbn: FindByName[L, K]): Aux[L, K, fbn.Out] = fbn | |
implicit def headByName[T <: HList, K, V] | |
: Aux[FieldType[K, V] :: T, K, V] = | |
new FindByName[FieldType[K, V] :: T, K] { | |
type Out = V | |
def apply(l: FieldType[K, V] :: T): Out = l.head | |
} | |
implicit def tailByName[H, T <: HList, K, V](implicit | |
fbn: FindByName[T, K]) | |
: Aux[H :: T, K, fbn.Out] = | |
new FindByName[H :: T, K] { | |
type Out = fbn.Out | |
def apply(l: H :: T): Out = fbn(l.tail) | |
} | |
} | |
def pluck[A, T, R <: HList](col: List[A], item: String)(implicit | |
gen: LabelledGeneric.Aux[A, R], | |
bn: FindByName.PrettyAux[A, R, Symbol @@ item.type, T]) | |
: List[T] = col.map(x ⇒ bn(gen.to(x))) | |
def test() = { | |
case class Foo(foo: String, bar: Int, baz: Boolean) | |
val xs = List(Foo("f", 42, true), Foo("g", 1337, false)) | |
val foos: List[String] = pluck(xs, "foo") | |
val bars: List[Int] = pluck(xs, "bar") | |
val bazs: List[Boolean] = pluck(xs, "baz") | |
println(s"foos = ${foos}") // => foos = List(f, g) | |
println(s"bars = ${bars}") // => bars = List(42, 1337) | |
println(s"bazs = ${bazs}") // => bazs = List(true, false) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment