scala - shapeless convert case class to HList and skip all option fields -


i have next class:

case class foo(a: option[int], b: option[string], c: option[double]) 

as can see, fields optional, want convert class hlist or tuple, like

val f1 = foo(some(1) , none, some(3d)) val f2 = foo(none, "foo")  val result1 = f1.to[int::double::hnil] // => 1::3d val result2 = f2.to[string::hnil] // "foo" 

is possible, without reflection?

it might possible existing type classes in shapeless (something nattrel , removeall), i'm not 100% sure of that, , case i'd write own type class:

import shapeless._  trait optionalpieces[l <: hlist, s <: hlist] {   def apply(l: l): option[s] }  object optionalpieces extends lowpriorityoptionalpieces {   implicit val hniloptionalpieces: optionalpieces[hnil, hnil] =     new optionalpieces[hnil, hnil] {       def apply(l: hnil): option[hnil] = some(hnil)     }    implicit def hconsoptionalpiecesmatch[h, t <: hlist, s <: hlist](implicit     opt: optionalpieces[t, s]   ): optionalpieces[option[h] :: t, h :: s] =     new optionalpieces[option[h] :: t, h :: s] {       def apply(l: option[h] :: t): option[h :: s] = {         h <- l.head         t <- opt(l.tail)       } yield h :: t     } }  sealed class lowpriorityoptionalpieces {   implicit def hconsoptionalpiecesnomatch[h, t <: hlist, s <: hlist](implicit     opt: optionalpieces[t, s]   ): optionalpieces[option[h] :: t, s] =     new optionalpieces[option[h] :: t, s] {       def apply(l: option[h] :: t): option[s] = opt(l.tail)     } } 

this witnesses l contains at least of elements of s wrapped in option, in order, , gives way unwrap them @ runtime (safely).

we can define syntax helper class this:

implicit class optionalpiecessyntax[a, r <: hlist](a: a)(implicit   gen: generic.aux[a, r] ) {   def to[s <: hlist](implicit op: optionalpieces[gen.repr, s]): option[s] =     op(gen.to(a)) } 

and then:

scala> val f1 = foo(some(1) , none, some(3d)) f1: foo = foo(some(1),none,some(3.0))  scala> val f2 = foo(none, some("foo"), none) f2: foo = foo(none,some(foo),none)  scala> val result1 = f1.to[int :: double :: hnil] result1: option[shapeless.::[int,shapeless.::[double,shapeless.hnil]]] = some(1 :: 3.0 :: hnil)  scala> val result2 = f2.to[string :: hnil] result2: option[shapeless.::[string,shapeless.hnil]] = some(foo :: hnil) 

if wanted exceptions, call .get in syntax class, seems bad idea.


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -