import shapeless.Generic class Playground { class ScalaStdlibTypes { class ScalaConcreteTypesWithTypes { type Rect = (Int, Int) type Circle = Int type Shape = Either[Rect, Circle] def area(s: Shape) = s match { case Left((a, b)) => a*b case Right(a) => math.Pi*a*a } val rect: Shape = Left(4, 2) val circle: Shape = Right(1) println(area(rect), area(circle)) } val concrete_types = new ScalaConcreteTypesWithTypes class ScalaGenericTypes { trait Shape case class Rect(a: Int, b: Int) extends Shape case class Circle(a: Int) extends Shape def area(s: Shape) = s match { case Rect(a, b) => a*b case Circle(a) => math.Pi*a*a } val rect = new Rect(3, 4) val circle = new Circle(3) println(area(rect)) } val generic_types = new ScalaGenericTypes } class ShapelessGenericTypes { class FromTuples { import shapeless.{HList, ::, HNil} type testType = Int :: Int :: HNil val k: testType = (1 :: 1 :: HNil) // manual construction of a "repr" (generic representation of a type) from a tuple val newType = Generic[(Int, Int)] println(newType.to((1, 1))) } class FromCaseClasses { trait Shape case class Rect(a: Int, b: Int) extends Shape val rectGen = Generic[Rect] println(rectGen) } val case_classes = new FromCaseClasses } // val stdlib_types = new ScalaStdlibTypes val shapless_generic_types = new ShapelessGenericTypes class GenericCSVEncoder { trait CSVEncoder[A] { // generic typeclass that defines the encode operation def encode(s: A): List[String] } def writeCSV[A](vals: List[A])(implicit enc: CSVEncoder[A]): String = vals.map(v => enc.encode(v).mkString(",")).mkString("\n") /** Simple example with a case class */ case class Employee(a: String, b: Int) implicit val employeeEncoder: CSVEncoder[Employee] = { new CSVEncoder[Employee] { def encode(e: Employee): List[String] = List(e.a, e.b.toString) } } val employees = List(Employee("a", 1), Employee("b", 2)) println(writeCSV(employees)) } val generic_csv_encoder = new GenericCSVEncoder class ShapelessCSVEncoder { trait CSVEncoder[A] { def encode(s: A): List[String] } } } object main { def main(args: Array[String]): Unit = { new Playground() } }