scala - Missing Sized.unapply -
in object sized (in "shapeless/sized.scala") there unapplyseq, unfortunately doesn't provide static checking. example code below fail @ runtime matcherror:
sized(1, 2, 3) match { case sized(x, y) => ":(" } it better if there unapply method instead, returning option of tuple, , concrete shape of tuple constructed according size of sized instance. example:
sized(1) => x sized(1, 2) => (x, y) sized(1, 2, 3) => (x, y, z) in case previous code snippet fail compile constructor cannot instantiated expected type.
please me implement unapply object sized. method implemented anywhere?
thanks in advance!
this possible (at least sized n less 23), approach can think of (barring macros, etc.) kind of messy. first need type class that'll convert sized collections hlists:
import shapeless._, nat._0 import scala.collection.generic.istraversablelike trait sizedtohlist[r, n <: nat] extends depfn1[sized[r, n]] { type out <: hlist } object sizedtohlist { type aux[r, n <: nat, out0 <: hlist] = sizedtohlist[r, n] { type out = out0 } implicit def emptysized[r]: aux[r, nat._0, hnil] = new sizedtohlist[r, _0] { type out = hnil def apply(s: sized[r, _0]) = hnil } implicit def othersized[r, m <: nat, t <: hlist](implicit sth: aux[r, m, t], itl: istraversablelike[r] ): aux[r, succ[m], itl.a :: t] = new sizedtohlist[r, succ[m]] { type out = itl.a :: t def apply(s: sized[r, succ[m]]) = s.head :: sth(s.tail) } def apply[r, n <: nat](implicit sth: sizedtohlist[r, n]): aux[r, n, sth.out] = sth def tohlist[r, n <: nat](s: sized[r, n])(implicit sth: sizedtohlist[r, n] ): sth.out = sth(s) } and can define extractor object uses conversion:
import ops.hlist.tupler object safesized { def unapply[r, n <: nat, l <: hlist, t <: product](s: sized[r, n])(implicit itl: istraversablelike[r], sth: sizedtohlist.aux[r, n, l], tupler: tupler.aux[l, t] ): option[t] = some(sth(s).tupled) } and then:
scala> val safesized(x, y, z) = sized(1, 2, 3) x: int = 1 y: int = 2 z: int = 3 but:
scala> val safesized(x, y) = sized(1, 2, 3) <console>:18: error: wrong number of arguments object safesized val safesized(x, y) = sized(1, 2, 3) ^ <console>:18: error: recursive value x$1 needs type val safesized(x, y) = sized(1, 2, 3) ^ as desired.
Comments
Post a Comment