Skip to content

Instantly share code, notes, and snippets.

@aloiscochard
Created April 13, 2012 17:45
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 aloiscochard/2378723 to your computer and use it in GitHub Desktop.
Save aloiscochard/2378723 to your computer and use it in GitHub Desktop.
Scala DSL design: Avoiding TupleX boilerplate using HList
package object field {
case class Field[T]()
val name = Field[String]()
val age = Field[Int]()
val admin = Field[Boolean]()
}
package object hlist {
import shapeless._
import TypeOperators._
import NatTRel._
import Tuples._
def record[P <: Product, L <: HList](p: P)
(implicit hl: HListerAux[P, L], t: NatTRel[L, field.Field, Id]): Record[L, t.Out] = record(p.hlisted)
def record[L <: HList](l: L)(implicit t: NatTRel[L, field.Field, Id]) = Record[L, t.Out](l)
case class Record[L <: HList, T <: HList](fields: L)
implicit def recordOps[L <: HList, T <: HList](record: Record[L, T])(implicit tupler: Tupler[T]) =
RecordOps[L, T, tupler.Out](record)
case class RecordOps[L <: HList, T <: HList, P <: Product](record: Record[L, T]) {
def set(v: P) = v
def update(f: P => P) = f
}
import field._
def usage {
record(name, age).set("Alois Cochard", 26)
record(name, age, admin).set("Alois Cochard", 26, true)
record(name, age).update(x => (x._1 + "*", x._2 + 1))
record(name, age, admin).update(x => (x._1 + "*", x._2 + 1, !x._3))
}
}
package object tuplex {
import field._
def record[T0, T1](fields: (Field[T0], Field[T1])) = Record2(fields)
case class Record2[T0, T1](fields: (Field[T0], Field[T1])) {
def set(v: Tuple2[T0, T1]) = v
def update(f: Tuple2[T0, T1] => Tuple2[T0, T1]) = f
}
def usage = {
record(name, age).set("Alois Cochard", 26)
record(name, age).update(x => (x._1 + "*", x._2 + 1))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment