Überladungsmethoden basierend auf Generika

Aug 29 2020

Ich möchte eine auf Generika basierende Methode überladen - also so etwas:

case class Indexed2dArr[Dim0Type, Dim1Type] (
  indices: (List[Dim0Type], List[Dim1Type]),
  array: List[List[Float]],
) {
  def getSliceAtIndexLocation(i: Dim0Type): (List[Dim1Type], List[Float]) = ???
  def getSliceAtIndexLocation(i: Dim1Type): (List[Dim0Type], List[Float]) = ???
}

Wenn getSliceAtIndexLocationalso mit einem Parameter von aufgerufen wird Dim0Type, wird ein eindimensionales Segment des ursprünglichen Arrays mit einem Index von zurückgegeben Dim1Type. Und umgekehrt, um mit anzurufen Dim1Type.

Dies führt zu einem double definitionCompilerfehler - dass die beiden Methoden nach dem Löschen des Typs denselben Typ haben, wobei dieser Typ ist (i: Object): Tuple2. Gibt es einen gültigen Weg, um dies zu streiten, oder ist es direkt unmöglich?

Antworten

3 DmytroMitin Aug 29 2020 at 15:34

Versuchen Sie es entweder DummyImplicit

case class Indexed2dArr[Dim0Type, Dim1Type] (
  indices: (List[Dim0Type], List[Dim1Type]),
  array: List[List[Float]],
) {
  def getSliceAtIndexLocation(i: Dim0Type): (List[Dim1Type], List[Float]) = ???
  def getSliceAtIndexLocation(i: Dim1Type)(implicit 
    di: DummyImplicit): (List[Dim0Type], List[Float]) = ???
}

oder Typklasse Muster

case class Indexed2dArr[Dim0Type, Dim1Type] (
  indices: (List[Dim0Type], List[Dim1Type]),
  array: List[List[Float]],
) {
  def getSliceAtIndexLocation[A](i: A)(implicit tc: TC[A]): tc.Out = tc(i)

  trait TC[A] {
    type B
    type Out = TC.MkOut[B]
    def apply(i: A): Out
  }
  object TC {
    type MkOut[B] = (List[B], List[Float])

    type Aux[A, B0] = TC[A] { type B = B0 }
    def instance[A, B0](f: A => MkOut[B0]): Aux[A, B0] = new TC[A] {
      override type B = B0
      override def apply(i: A): Out = f(i)
    }
  
    implicit val dim0Type: Aux[Dim0Type, Dim1Type] = instance(i => ???)
    implicit val dim1Type: Aux[Dim1Type, Dim0Type] = instance(i => ???)
  }
}

oder Magnetmuster

import scala.language.implicitConversions

case class Indexed2dArr[Dim0Type, Dim1Type] (
  indices: (List[Dim0Type], List[Dim1Type]),
  array: List[List[Float]],
) {
  def getSliceAtIndexLocation(m: Magnet): m.Out = m()

  trait Magnet {
    type B
    type Out = Magnet.MkOut[B]
    def apply(): Out
  }
  object Magnet {
    type MkOut[B] = (List[B], List[Float])

    type Aux[B0] = Magnet { type B = B0 }
    def instance[B0](x: MkOut[B0]): Aux[B0] = new Magnet {
      override type B = B0
      override def apply(): Out = x
    }

    implicit def dim0Type(i: Dim0Type): Aux[Dim1Type] = instance(???)
    implicit def dim1Type(i: Dim1Type): Aux[Dim0Type] = instance(???)
  }
}