Skip to content

Instantly share code, notes, and snippets.

@tel
Last active December 13, 2020 18:57
Show Gist options
  • Save tel/ae4aadccd22665a6714907f71ad53704 to your computer and use it in GitHub Desktop.
Save tel/ae4aadccd22665a6714907f71ad53704 to your computer and use it in GitHub Desktop.
package com.jspha.maia
import scala.language.higherKinds
import shapeless._
import shapeless.ops.hlist.Mapped
trait Maia {
trait Api {
type Fields <: HList
}
sealed trait Target
sealed trait Atomic[A] extends Target
sealed trait Nested[T] extends Target
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
sealed trait Person extends Api {
type Fields = Atomic[String] :: HNil
}
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
trait Request[T <: Api] {
import Request.Elem
type Rec <: HList
val mapped: Mapped.Aux[T#Fields, Elem, Rec]
val record: Rec
}
object Request {
sealed trait Elem[_]
case class ElemAtomic[A](a: A) extends Elem[Atomic[A]]
case class ElemNested[T <: Api](rec: Request[T]) extends Elem[Nested[T]]
type Aux[T <: Api, Rec0 <: HList] = Request[T] { type Rec = Rec0 }
def build[T <: Api, Rec0 <: HList](record0: Rec0)(
implicit mapped0: Mapped.Aux[T#Fields, Elem, Rec0]): Request[T] =
new Request[T] {
type Rec = Rec0
val mapped = mapped0
val record = record0
}
class Builder[T <: Api] {
def apply[Rec0 <: HList](record0: Rec0)(
implicit mapped0: Mapped.Aux[T#Fields, Elem, Rec0]): Request[T] =
new Request[T] {
type Rec = Rec0
val mapped = mapped0
val record = record0
}
}
def apply[T <: Api]: Builder[T] =
new Builder[T]
}
val req0: Request[Person] = new Request[Person] {
import Request._
type Rec = Request.Elem[Atomic[String]] :: HNil
val mapped = implicitly[Mapped.Aux[Person#Fields, Elem, Rec]]
val record = ElemAtomic("Hi") :: HNil
}
val req1: Request[Person] =
Request.build[Person, Request.Elem[Atomic[String]] :: HNil](
Request.ElemAtomic("Hi") :: HNil)
val req2: Request[Person] =
Request[Person](Request.ElemAtomic("Hi") :: HNil)
}
// [info] Compiling 1 Scala source to /Users/tel/Dropbox/proj/scala/maia2/target/scala-2.12/classes...
// [error] /Users/tel/Dropbox/proj/scala/maia2/src/main/scala-2.12/com/jspha/maia/Maia.scala:77: could not find implicit value for parameter mapped0: shapeless.ops.hlist.Mapped.Aux[Maia.this.Person#Fields,Maia.this.Request.Elem,shapeless.::[Maia.this.Request.ElemAtomic[String],shapeless.HNil]]
// [error] Request[Person](Request.ElemAtomic("Hi") :: HNil)
// [error] ^
// [error] one error found
// [error] (compile:compileIncremental) Compilation failed
// [error] Total time: 0 s, completed Apr 7, 2017 5:41:27 PM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment