Created
April 13, 2012 17:45
-
-
Save aloiscochard/2378723 to your computer and use it in GitHub Desktop.
Scala DSL design: Avoiding TupleX boilerplate using HList
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
package object field { | |
case class Field[T]() | |
val name = Field[String]() | |
val age = Field[Int]() | |
val admin = Field[Boolean]() | |
} |
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
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)) | |
} | |
} |
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
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