Converting an example to HList

18 views
Skip to first unread message

Peter Schmitz

unread,
May 27, 2015, 11:29:26 AM5/27/15
to shapel...@googlegroups.com
I don't know if this is the right place to ask but I am got stuck with instanceOf casts.

Here a minimized example:

Say I have a base trait with some abstract members:

  trait C {
    type M
    type A
    val upt: A => M => M
  }


And two examples instances:

  object C1 extends C {
   
case class M(s: String)
   
case class A(c: Char)
    val upt
: A => M => M = { case A(c) => m => m copy (s = m.s + c) }
 
}


 
object C2 extends C {
   
case class M(l: Long)
   
case class A(i: Int)
    val upt
: A => M => M = { case A(i) => m => m copy (l = m.l + i) }
 
}


Now I want to wrap a list of C's into a new class CS:

  class CS(val cSubs: Seq[C]) extends C {
   
case class M(mSubs: Seq[C#M])
   
sealed trait A
   
case class Asub[A0 <: C#A](idx: Int, aSub: A0) extends A
    val upt
: A => M => M = {
     
case Asub(idx, aSub) =>
        m
=> m copy (mSubs = m.mSubs.zip(cSubs).zipWithIndex map {
         
case ((mSub, cSub), `idx`) => cSub.upt(aSub.asInstanceOf[cSub.A])(mSub.asInstanceOf[cSub.M])
         
case ((mSub, cSub), _)     => mSub
       
})

   
}
 
}

Don't wonder where the Asub(idx, aSub) instances finally come from, this is a minimized example.

For example I can run the following lines:

  val c1m1 = C1.M("Hey")
  val c1m2
: C1.M = C1.upt(C1.A('!'))(c1m1)


  val cs = new CS(Seq(C1, C2))
  val csm1
= cs.M(Seq[C#M](C1.M("Hey"), C2.M(42L)))
  cs
.upt(cs.Asub(0, C1.A('!')))(csm1)
  cs
.upt(cs.Asub(1, C2.A(8)))(csm1)


But how can I use a HList instead of a Seq to get rid of this instanceOf? I tried but failed. I started with ensuring that every element in an argument HList conforms to type C:

  trait ConformsTo[L <: HList, T]
  
object ConformsTo {
    
implicit def hnil[X]: HNil ConformsTo X = null
    
implicit def cons[X, X0 <: X, T <: HList](implicit ev: T ConformsTo X): (X0 :: T) ConformsTo X = null
  
}


  
object CS {
    
def apply[L <: HList](l: L)(implicit conforms: L ConformsTo C) = new CS(l)
  
}

  class CS[L <: HList](val l: L) extends C { ... }


Now I got stuck with mapping and zipWithIndex and modelling case class Asub(nat: Nat, ...) ....

I appreciate any ideas.

Thank you!

Peter


Reply all
Reply to author
Forward
0 new messages