将Scala泛型类型限制为仅具有运算符重载的类型

将Scala泛型类型限制为仅具有运算符重载的类型,scala,generics,Scala,Generics,是否可以将Scala泛型类型约束为仅重载了特定运算符的类型 例如: def foo[T](...):T = {...} foo(...) * .70 搜索谷歌还没有找到解决方案。我考虑将T限制为Numeric类型(或scala的等效类型),但我希望允许用户定义自定义类型并为这些运算符指定自己的行为。是的,有所谓的结构类型。您可以按如下方式定义它们: def foo[T <: {def yourOperator:Unit}(...) : T = {...} def foo[T是的,有所谓

是否可以将Scala泛型类型约束为仅重载了特定运算符的类型

例如:

def foo[T](...):T = {...}
foo(...) * .70

搜索谷歌还没有找到解决方案。我考虑将T限制为Numeric类型(或scala的等效类型),但我希望允许用户定义自定义类型并为这些运算符指定自己的行为。

是的,有所谓的结构类型。您可以按如下方式定义它们:

def foo[T <: {def yourOperator:Unit}(...) : T = {...}

def foo[T是的,有所谓的结构类型。您可以按如下方式定义它们:

def foo[T <: {def yourOperator:Unit}(...) : T = {...}
def foo[T使用类型类

trait Multiply[A] {
  def multiply(x: A, y: Double): A
}

object Multiply {
  def apply[A](implicit instance: Multiple[A]): Multiply[A] = instance

  trait Ops[A] {
    def typeClassInstance: Multiply[A]
    def self: A
    def *(y: Double): A = typeClassInstance.multiply(self, y)
  }

  trait ToMultiplyOps {
    implicit def toMultiplyOps[A](target: A)(implicit tc: Multiply[A]): Ops[A] = new Ops[A] {
      val self = target
      val typeClassInstance = tc
    }
  }

  trait AllOps[A] extends Ops[A] {
    def typeClassInstance: Multiply[A]
  }

  object ops {
    implicit def toAllMultiplyOps[A](target: A)(implicit tc: Multiply[A]): AllOps[A] = new AllOps[A] {
      val self = target
      val typeClassInstance = tc
    }
  }
}
(请注意,这相当于Michael Pilquist的库生成的内容,因此您实际上不需要所有这些样板文件)

然后,您的用户可以执行以下操作:

case class Foo(x: Int)

object Foo {
  implicit val multiplyFoo: Multiply[Foo] = new Multiply[Foo] {
    def multiply(foo: Foo, y: Double): Foo = ???
  }
}

Foo(42) * 3.1415
使用typeclass

trait Multiply[A] {
  def multiply(x: A, y: Double): A
}

object Multiply {
  def apply[A](implicit instance: Multiple[A]): Multiply[A] = instance

  trait Ops[A] {
    def typeClassInstance: Multiply[A]
    def self: A
    def *(y: Double): A = typeClassInstance.multiply(self, y)
  }

  trait ToMultiplyOps {
    implicit def toMultiplyOps[A](target: A)(implicit tc: Multiply[A]): Ops[A] = new Ops[A] {
      val self = target
      val typeClassInstance = tc
    }
  }

  trait AllOps[A] extends Ops[A] {
    def typeClassInstance: Multiply[A]
  }

  object ops {
    implicit def toAllMultiplyOps[A](target: A)(implicit tc: Multiply[A]): AllOps[A] = new AllOps[A] {
      val self = target
      val typeClassInstance = tc
    }
  }
}
(请注意,这相当于Michael Pilquist的库生成的内容,因此您实际上不需要所有这些样板文件)

然后,您的用户可以执行以下操作:

case class Foo(x: Int)

object Foo {
  implicit val multiplyFoo: Multiply[Foo] = new Multiply[Foo] {
    def multiply(foo: Foo, y: Double): Foo = ???
  }
}

Foo(42) * 3.1415

10/10会再次提出问题。谢谢!除了像
+
*
这样的方法不能精确工作之外,这些方法会使用相同类型的第二个参数。如果您尝试编写类似
def foo的内容[T 10/10会再次提出问题。谢谢!除了像
+
*
这样的方法不能精确工作之外,这些方法使用相同类型的第二个参数。如果您尝试编写类似
def foo[T