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

Popular posts from this blog

javascript - jquery or ashx not working -

opencv - DataType<cv::detail::deriv_type>::depth what is it used for -

python 3.x - Mapping specific letters onto a list of words -