基于泛型的重载方法 [英] Overloading methods based on generics

查看:61
本文介绍了基于泛型的重载方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想重载基于泛型的方法-像这样:

I'd like to overload a method based on generics - so something like this:

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]) = ???
}

因此,如果使用参数 Dim0Type 调用 getSliceAtIndexLocation ,它将返回原始数组的一维切片,索引为 Dim1Type .反之亦然,使用 Dim1Type 进行调用.

So if getSliceAtIndexLocation is called with a parameter of Dim0Type, it returns a single-dimensioned slice of the orginal array, with an index of Dim1Type. And vice-versa for calling with Dim1Type.

这将引发双重定义编译器错误-类型擦除后,这两种方法具有相同的类型,此类型为(i:Object):Tuple2 .有没有有效的方法可以解决这个问题?还是不可能直接解决?

This raises a double definition compiler error - that the two methods have the same type after type erasure, this type being (i: Object): Tuple2. Is there a valid way to wrangle this or is it straight-up impossible?

推荐答案

尝试使用 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]) = ???
}

类型类模式

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 => ???)
  }
}

磁铁模式

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(???)
  }
}

这篇关于基于泛型的重载方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆