2015-06-19 5 views
5

Ich zeichne eine leere auf, wie das folgende ohne Betrug und Verwendung asInstanceOf erreichen.Pattern-Matching abhängigen Typen - wie AsInstanceOf zu vermeiden?

Angenommen, ich habe einen willkürlich versiegelten Objekttyp mit jeweils eigenen Typmitgliedern.

sealed trait Part { type A } 
    case object P1 extends Part { override type A = String } 
    case object P2 extends Part { override type A = Int } 

Nun sage ich ein P und ein P.A Wert zusammen bündeln ...

trait PartAndA { 
    val p: Part 
    val a: p.A 
    } 

    object PartAndA { 
    type Aux[P <: Part] = PartAndA {val p: P} 

    def apply(_p: Part)(_a: _p.A): Aux[_p.type] = 
     new PartAndA { 
     override val p: _p.type = _p 
     override val a   = _a 
     } 
    } 

Wie kann ich sicher die folgende Erschöpfung erreichen Kontrolle und ohne manuelle Abgüsse?

def fold[A](pa: PartAndA)(p1: PartAndA.Aux[P1.type] => A, 
          p2: PartAndA.Aux[P2.type] => A): A = 
    pa.p match { 
     case P1 => p1(pa.asInstanceOf[PartAndA.Aux[P1.type]]) 
     case P2 => p2(pa.asInstanceOf[PartAndA.Aux[P2.type]]) 
    } 

Antwort

1

Ich denke, Ihr Problem mit jvm type erasure verbunden ist. Ohne sie könnte Ihr Problem zu vereinfachen:

sealed trait Part { type A } 
case class P1() extends Part { override type A = String } 
case class P2() extends Part { override type A = Int } 

trait PartAndA[P <: Part] { 
    val p: P 
    val a: p.A 
} 

object PartAndA { 
    type Aux[P <: Part] = PartAndA[P] 

    def apply(_p: Part)(_a: _p.A): PartAndA[_p.type] = 
    new PartAndA[_p.type] { 
     override val p: _p.type = _p 
     override val a   = _a 
    } 
} 

def fold[A, T: ClassTag](pa: PartAndA[T])(p1: PartAndA[P1] => A, 
          p2: PartAndA[P2] => A): A = 
    pa match { 
    case s: PartAndA[P1] => p1(pa) // here P1 is lost, err 
    case i: PartAndA[P2] => p2(pa) // here P2 is lost, err 
    } 

Nach meiner Kenntnis gibt es keine kürzeres (als dein oder mit typeTags/classTags) Abhilfe von Jvm Typ Löschung.

+0

Ah ja, das wäre der Fall, wenn ich auf 'pa' passe, aber' pa.p' ist konkret und wir können darauf ohne Löschprobleme abgleichen. Ich weiß einfach nicht, wie man einen Beweis baut, der sagt, wenn ich den 'pa.p' Typ kenne, dann kenne ich den' PartAndA.Aux' Typ. – Golly

Verwandte Themen