Travis Brown @travisbrown
scala> import shapeless.syntax.std.tuple._
import shapeless.syntax.std.tuple._
scala> ('foo, "bar") ++ (1, 2.0, 3L)
res0: (Symbol, String, Int, Double, Long) = ('foo,bar,1,2.0,3)
import shapeless._, ops.hlist.Align
class SameFieldsConverter[T] {
def apply[S, SR <: HList, TR <: HList](s: S)(implicit
genS: LabelledGeneric.Aux[S, SR],
genT: LabelledGeneric.Aux[T, TR],
align: Align[SR, TR]) = genT.from(align(genS.to(s)))
}
def convertTo[T] = new SameFieldsConverter[T]
case class A(foo: Int, bar: String)
case class B(bar: String, foo: Int)
val b: B = convertTo[B](A(12, "foo"))
You could do this with a macro, but...
...the best macro is a macro you don't maintain
We want to avoid rolling our own:
Building RequestReader
with ~
(before)
import io.finch.request._
case class User(id: Long, name: String)
val reader: RequestReader[User] =
param("id").as[Long] ~ param("name") ~> User
This is awesome, but...
~
Building RequestReader
with ::
(now)
val reader: RequestReader[User] =
(param("id").as[Long] :: param("name")).as[User]
Now in finch
::
HList
readers
val reader: RequestReader[User] =
RequestReader.to[User].fromParams
Out for review
DecodeRequest
instances for field typesAll at compile time
PRequestReader
is a monadA => Future[?]
(P)RequestReader
are type aliasesmap
, flatMap
embedFlatMap
is flatMapK
, etc.toFuture
becomes pure[Future]
Validated
for error accumulation