Skip to content

Instantly share code, notes, and snippets.

@timcharper
Last active August 29, 2015 14:27
Show Gist options
  • Save timcharper/7f9ddfea1193b02e45c8 to your computer and use it in GitHub Desktop.
Save timcharper/7f9ddfea1193b02e45c8 to your computer and use it in GitHub Desktop.
package m
import shapeless.HMap
object leData {
object Name
object Age
object Address
object Street
object City
object State
class Direction[K, V]
class Person[K, V]
implicit val personNameAsString = new Person[Name.type , String]
implicit val personAgeAsInt = new Person[Age.type , Int]
implicit val personAddressAsDirection = new Person[Address.type , HMap[Direction]]
implicit val directionStreetAsString = new Direction[Street.type , String]
implicit val directionCityAsString = new Direction[City.type , String]
implicit val directionStateAsString = new Direction[State.type , String]
}
object EnrichedTrav {
// Enrich HMap to provide \ operator for types HMap and Option[HMap]
implicit class Navi[R[_, _]](h: HMap[R]) {
def \[K, V](k: K)(implicit ev : R[K, V]) : Option[V] = h.get(k)
}
implicit class NaviOpt[R[_, _]](h: Option[HMap[R]]) {
def \[K, V](k: K)(implicit ev : R[K, V]) : Option[V] = h.flatMap(_.get(k))
}
}
object Main extends App {
import EnrichedTrav._
import leData._ // you do need to import the type map
val hm = HMap[Person].apply(
Name -> "Tim",
Age -> 33,
Address -> HMap[Direction](
Street -> "Very Street",
City -> "SL",
State -> "UT"))
// Compiler knows result is Option[Int]
val age = hm \ Age
// Compiler knows result is Option[String]
val address = hm \ Address \ City
// Doesn't compile; Compiler knows that Name can not be a member of HMap[Direction]
val addressName = hm \ Address \ Name
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment