scala - Polymorphic functions with constant return type in Shapeless -
scala - Polymorphic functions with constant return type in Shapeless -
long story short, i'm trying figure out how define function generic input single-typed output.
the background: continuation of mapping on shapeless record. after travis's first-class answer, have following:
import shapeless._ import poly._ import syntax.singleton._ import record._ type queryparams = map[string, seq[string]] trait requestparam[t] { def value: t /** convert value query parameter representation */ def toqueryparams: seq[(string, string)] /** mark parameter auto-propagation in new urls */ def propagate: boolean protected def querystringpresent(qs: string, allparams: queryparams): boolean = allparams.get(qs).nonempty } type requestparambuilder[t] = queryparams => requestparam[t] def booleanrequestparam(paramname: string, willpropagate: boolean): requestparambuilder[boolean] = { params => new requestparam[boolean] { def propagate: boolean = willpropagate def value: boolean = querystringpresent(paramname, params) def toqueryparams: seq[(string, string)] = seq(paramname -> "true").filter(_ => value) } } def stringrequestparam(paramname: string, willpropagate: boolean): requestparambuilder[option[string]] = { params => new requestparam[option[string]] { def propagate: boolean = willpropagate def value: option[string] = params.get(paramname).flatmap(_.headoption) def toqueryparams: seq[(string, string)] = value.map(paramname -> _).toseq } }
in reality, next class constructor takes map read query string parameter, simplicity's sake, i'm defining val
:
val requestparams = map("no_ads" -> seq("true"), "edition" -> seq("us")) // in reality, there many more possible parameters, simplified val options = ('adsdebug ->> booleanrequestparam("ads_debug", true)) :: ('hideads ->> booleanrequestparam("no_ads", true)) :: ('edition ->> stringrequestparam("edition", false)) :: hnil object bind extends fieldpoly { implicit def rpb[t, k](implicit witness: witness.aux[k]): case.aux[ fieldtype[k, requestparambuilder[t]], fieldtype[k, requestparam[t]] ] = atfield(witness)(_(requestparams)) } // create queryable alternative values record binding request parameters val boundoptions = options.map(bind)
this lets me do:
boundoptions.get('hideads).value // -> true
the problem: want able reserialize options have propagate = true
. basically, need filter hlist
on propagate
field of every member, should homecoming boolean
, , have each parameter reserialize seq[(string, string)]
. i've tried following:
object propagatefilter extends (requestparam ~> const[boolean]) { override def apply[t](r: requestparam[t]): boolean = r.propagate } object unbind extends (requestparam ~> const[seq[(string, string)]]) { override def apply[t](r: requestparam[t]): seq[(string, string)] = r.toqueryparams } // reserialize query string options should propagated val propagatedparams = boundoptions.values.filter(propagatefilter).map(unbind).tolist // (followed conventional collections methods)
, doesn't functions. got next error:
<console>:31: error: type mismatch; found : boolean required: shapeless.const[t] (which expands to) anyref{type λ[t] = t} override def apply[t](r: requestparam[t]) = r.propagate
i believe i'm taking wrong approach function that's supposed have polymorphic input monomorphic output.
other failed attempts:
object propagatefilter extends poly1 { implicit def default[t](implicit st: case.aux[requestparam[t], boolean]) = at[requestparam[t]](_.propagate) }
and
def propagate[t](x: requestparam[t]): boolean = x.propagate
and
object propagatefilter extends poly1 { implicit def default = at[requestparam[_]](_.propagate) }
and
object propagatefilter extends fieldpoly { implicit def rpb[t, k](implicit witness: witness.aux[k]): case.aux[ fieldtype[k, requestparam[t]], boolean ] = atfield(witness)(_.propagate) }
none of work, due own misunderstanding of what's going on.
scala shapeless
Comments
Post a Comment