类型类,隐式转换,多个类型参数

时间:2019-05-28 23:56:26

标签: scala typeclass implicit

我正在尝试创建具有多个类型参数的类型类。 我试图根据类型隐式调用该方法

我正在显示一个我尝试过的代码的简单片段。

object operation {
// Define generic trait class
  trait Operator[T, U] {
    def addition[T, U](l: U, r: T)(implicit p: Parameters): U
  }


  object Operator {
// Define type class.
    implicit object IntOperator extends Operator[Int, Float] {
      def addition(l: Int, r: Float): Float = {
        r
      }
    }
  }
// Create mapping for implicit call.
  def addition[T, U](l: T, r: U)(implicit op: Operator[T, U]): U = op.addition(l, r,)
  }

import  operation._

def fn(a: UInt, b: Float)
addition(a,b)

如果我使用单个类型参数,即仅[T,U],则此代码可以正常编译。但是,如果我使用两个类型参数,即Operator [T,U],则加法(a,b)会抱怨 找不到参数Operator [T,U]的隐式。任何帮助将不胜感激。

我希望简化的代码段详细说明我要尝试做的事情。

1 个答案:

答案 0 :(得分:1)

只是让您知道它可以按预期进行编译和工作。

object operation {
  trait Operator[T, U] {
    def addition(l: T, r: U): U
  }

  object Operator {
    implicit final val IntFloatOperator: Operator[Int, Float] =
      new Operator[Int, Float] {
        override def addition(l: Int, r: Float): Float = l + r
      }
  }

  def addition[T, U](l: T, r: U)(implicit op: Operator[T, U]): U = op.addition(l, r)
}

def fn(a: Int, b: Float): Float = operation.addition(a, b)
fn(1, 10.0f) // 11.0F

编辑

处理评论,您可以:

1)提供所需的隐式。

def fn[T1 <: Int, T2 <: Float](a: T1, b: T2)(implicit op: Operator[T1, U1]): U1 =
  op.addition(a, b)

(注意:该方法的用户负责为其使用的类型在范围内具有类型为 Operator [T1,U1] 的隐式。)

2)明确召唤 IntFloatOperator

def fn [T1 <:Int,T2 <:Float](a:T1,b:T2):T2 =   隐式[Operator [Int,Float]]。addition(a,b)

(注意:通常提供一个定制的召唤师以减少样板。)

object Operator {
  // Summoner.
  def apply[T, U](implicit op: Operator[T, U]): Operator[T, U] = op

  ...
}

def fn[T1 <: Int, T2 <: Float](a: T1, b: T2): T2 =
  Operator[Int, Float].addition(a, b)