scala - Implicit Generic.Aux missing on conversion from Shapeless HList to case class -
i started learning scala , today decided wanted write csv parser load nicely case classes store data in rows (lists) of shapeless's hlist object exposure type-level programming.
here's have far:
// loadscsv.scala import shapeless._ import scala.collection.mutable trait loadscsv[a, t <: hlist] { val rows: mutable.mutablelist[t] = new mutable.mutablelist[t] def convert(t: t)(implicit gen: generic.aux[a, t]): = gen.from(t) def get(index: int): = { convert(rows(index)) } def load(file: string): unit = { val lines = io.source.fromfile(file).getlines() lines.foreach(line => rows += parse(line.split(","))) } def parse(line: array[string]): t }
and object that's loading data set:
// tennisdata.scala import shapeless._ case class tennisdata(weather:string, low:int, high:int, windy:boolean, play:boolean) object tennisdata extends loadscsv[tennisdata, string :: int :: int :: boolean :: boolean :: hnil] { load("tennis.csv") override def parse(line: array[string]) = { line(0) :: line(1).toint :: line(2).toint :: line(3).toboolean :: line(4).toboolean :: hnil } }
things seem working alright until added get() conversion hlist case class compilation error. why isn't implicit getting loaded , can fix or otherwise convert hlist case class?
error:(14, 17) not find implicit value parameter gen: shapeless.generic.aux[a,t] return convert(rows(index)) ^
i've been reading shapeless documentation , mentions area had been in flux between version 1 , 2, believe things should working on version of shapeless , scala suspect i've done incorrectly.
for reference, i'm running scala 2.11.6 , shapeless 2.2.2
you're close. problem scala isn't going propagate implicit requirements call chain automatically you. if need generic[a, t]
instance call convert
, you'll have make sure one's in scope every time call convert convert
. if a
, t
fixed (and case class-hlist
pair), shapeless generate 1 you. in get
method, however, compiler still knows nothing a
, t
except t
hlist
, need require instance again in order call convert
:
def get(index: int)(implicit gen: generic.aux[a, t]): = convert(rows(index))
everything should work fine after change.
note require instance @ trait level adding (abstract) method following:
implicit def gena: generic.aux[a, t]
then class implementing loadscsv
have implicit val gena
parameter (or supply instance in other way).
Comments
Post a Comment