Skip to content

Instantly share code, notes, and snippets.

@danslapman
Last active October 6, 2018 21:17
Show Gist options
  • Save danslapman/0f700973aa82e9d361e0fdfff4b4c123 to your computer and use it in GitHub Desktop.
Save danslapman/0f700973aa82e9d361e0fdfff4b4c123 to your computer and use it in GitHub Desktop.
Auto-generating patches for fields
import $ivy.`org.typelevel::cats-core:1.4.0`
import $ivy.`org.typelevel::kittens:1.1.1`
import cats._
import cats.data.{Validated, ValidatedNel}
//import cats.instances.list._
import cats.sequence._
import shapeless._
import shapeless.labelled._
import shapeless.record._
case class Yoba(id: Int, name: String)
type Vld[T] = ValidatedNel[String, T]
// Это у нас получится в результате .taggedField
val v1: Vld[FieldType[Witness.`'id`.T, Int]] =
// Надо выяснить, какого хрена не работает синтаксис "id" ->> _
Validated.valid(42).map(field[Witness.`'id`.T](_))
val v2: Vld[FieldType[Witness.`'name`.T, String]] =
Validated.valid("Peka").map(field[Witness.`'name`.T](_))
val values = v2 :: v1 :: HNil // Теперь нам не нужен mapN, просто сваливаем всё в HList
// Я намеренно перемешал поля
val result = values.sequence
object patchMaker extends Poly1 {
implicit def toPatch[K <: Symbol, V](implicit w: Witness.Aux[K]) = at[FieldType[K, V]] { field =>
s"Field '${w.value.name}' is set to '$field'"
}
}
result.map { fields =>
val lgen = LabelledGeneric[Yoba]
// Упорядочиваем поля в удобоваримом для lgen порядке и конвертируем в case class
val yoba = lgen.from(fields.align[lgen.Repr])
println(yoba) // Собрали наш доменный объект
val patches = fields.map(patchMaker).toList
println(patches) // Сгенерировали патчи
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment