【问题标题】:Type classes, implicit conversion, multiple type parameters类型类、隐式转换、多类型参数
【发布时间】:2019-05-28 23:56:25
【问题描述】:

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

我正在展示我尝试过的代码的简单 sn-p。

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] 的隐式。任何帮助将不胜感激。

我希望简化的代码 sn-p 详细说明我正在尝试做的事情。

【问题讨论】:

  • Parameters 是在哪里定义的,你为什么不在你的 IntOperator 上使用它,你为什么还要在 trait 上声明 TU?错字?最后一次添加调用是在 fn 内部完成的吗?如果不是,ab 是从哪里来的?
  • UInt 来自 spire.math 库吗?如果是这样,问题似乎是值类的隐式解析不使用底层类型的解析。 (我在编译你的代码时也遇到了麻烦——你肯定需要从 def addition 中删除类型参数并更正 IntOperator 的返回类型,以使其被识别为有效实现。)

标签: scala typeclass implicit


【解决方案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] 的隐式。) em>

2) 显式调用 IntFloatOperator

def fn[T1 <: int t2 float t1 b: 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)

【讨论】:

  • 我想我在尝试提问时过度简化了问题并引入了拼写错误。让我试着改写一下。但是,感谢您验证样本。我将尝试解决我的具体问题。 --- 问候
  • 好的。我想我现在可以复制错误了。如果我使 def fn[T<: int t2 float : t b: b op>
  • @ArrvindhShriraman 好吧,在这种情况下,错误是 "pretty clear" 它找不到隐含的,因为fn 没有以任何方式提供它。 - 我会假设在你的真实代码中你有一些与IntFloat 不同的东西(因为要求它们的子类型没有意义)。 - 所以,为了解决这个问题,有两种选择:1)你的方法也要求隐式,并且在某种程度上应该有一个隐式实例可用于正在使用的特定类型。 2)既然你问为什么它没有发现 IntOperator 隐含的,我猜你想使用它。我会编辑。
  • 是的;那是对的。我有自定义类型,在 fn 中我不知道 a 和 b 的类,我只知道它们的抽象,即 fn 本身是通用的。
  • 我尝试了您的选项 2 来隐式调用该方法,它在您提供的示例中有效,但不适用于我的代码。在我的代码中,它现在包含 T 与特定类型不匹配。我认为我必须重新发布我的问题并提供有关我的问题的更多详细信息才能使这项工作正常进行。
猜你喜欢
  • 2012-01-21
  • 2013-07-09
  • 1970-01-01
  • 2020-07-28
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
相关资源
最近更新 更多