需要两个隐式参数之一的 Scala 方法

Yev*_*iuk 4 scala implicit

如果我可以创建具有类似想法的方法,我很感兴趣:

def myMethod[T](param: T)(implicit oneOf: Either[TypeClass1[T], TypeClass2[T]]) = oneOf match ...
Run Code Online (Sandbox Code Playgroud)

我尝试使用默认参数(我在 akka 中看到过类似的东西):

def myMethod[T](param: T)(implicit t1: TypeClass1[T] = null, t2: TypeClass2[T] = null) = 
  if (t1 == null) ...
Run Code Online (Sandbox Code Playgroud)

但是,这样我就不能强制 Scala 编译器至少找到其中之一。

此外,我已经实现了从TypeClass1[T]toLeft[TypeClass1[T], TypeClass2[T]]和 from TC2to 的隐式转换Right,但是 Scala 编译器忽略了这种转换。

有没有办法做这样的事情?

Tim*_*Tim 10

显而易见的解决方案是创建一个可以使用TypeClass1或构造的新类型类TypeClass2。新类型类实现了myMethod两者通用的功能,并将其映射到TypeClass1或上的适当方法TypeClass2


下面是一个例子:

  trait TypeClass1[T] {
    def showOne = println("Typeclass 1")
  }

  trait TypeClass2[T] {
    def showTwo = println("Typeclass 2")
  }

  trait UnionTypeClass[T] {
    def show
  }

  object UnionTypeClass {
    implicit def t1[T](implicit ev: TypeClass1[T]) = new UnionTypeClass[T] {
      def show = ev.showOne
    }

    implicit def t2[T](implicit ev: TypeClass2[T]) = new UnionTypeClass[T] {
      def show = ev.showTwo
    }
  }


  implicit object IntClass extends TypeClass1[Int]
  implicit object StringClass extends TypeClass2[String]


  def myMethod[T](param: T)(implicit ev: UnionTypeClass[T]) = {
    ev.show
  }

  myMethod(0)
  myMethod("hello")
Run Code Online (Sandbox Code Playgroud)

这将打印

Typeclass 1
Typeclass 2
Run Code Online (Sandbox Code Playgroud)


Mar*_*lic 6

在 Scala 3 中,您可以像这样使用联合类型

trait Foo[A]
trait Bar[A]

given foo as Foo[Int] {}

def g[T](using Foo[T] | Bar[T]) = summon
foo[Int] // ok
Run Code Online (Sandbox Code Playgroud)