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

问题描述 投票:2回答:2

我是否有兴趣创建类似想法的方法:

def myMethod[T](param: T)(implicit oneOf: Either[TypeClass1[T], TypeClass2[T]]) = oneOf match ...

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

def myMethod[T](param: T)(implicit t1: TypeClass1[T] = null, t2: TypeClass2[T] = null) = 
  if (t1 == null) ...

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

此外,我已经实现了从TypeClass1[T]Left[TypeClass1[T], TypeClass2[T]]以及从TC2Right的隐式转换,但是Scala编译器忽略了这种转换。

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

scala implicit
2个回答
5
投票

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


这里是一个例子:

  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")

将打印

Typeclass 1
Typeclass 2

2
投票

在Scala 3中,您可能可以像这样使用union type

trait Foo[A]
trait Bar[A]

given foo as Foo[Int] {}

def g[T](using Foo[T] | Bar[T]) = summon
foo[Int] // ok
© www.soinside.com 2019 - 2024. All rights reserved.