如何“提取”类型参数来实例化另一个类

2023-12-07

以下 Scala 代码有效:

object ReducerTestMain extends App {

  type MapOutput = KeyVal[String, Int]

  def mapFun(s:String): MapOutput = KeyVal(s, 1)

  val red = new ReducerComponent[String, Int]((a: Int, b: Int) => a + b)

  val data = List[String]("a", "b", "c", "b", "c", "b")

  data foreach {s => red(mapFun(s))}
  println(red.mem)
  // OUTPUT: Map(a -> 1, b -> 3, c -> 2)
}

class ReducerComponent[K, V](f: (V, V) => V) {
  var mem = Map[K, V]()

  def apply(kv: KeyVal[K, V]) = {
    val KeyVal(k, v) = kv
    mem += (k -> (if (mem contains k) f(mem(k), v) else v))
  }
}

case class KeyVal[K, V](key: K, value:V)

我的问题是我想实例化ReducerComponent像这样:

val red = new ReducerComponent[MapOutput, Int]((a: Int, b: Int) => a + b)

甚至更好:

val red = new ReducerComponent[MapOutput](_ + _)

这意味着很多事情:

  1. 我想进行类型检查MapOutput属于类型KeyVal[K, C],
  2. 我想进行类型检查C与中使用的类型相同f,
  3. 我还需要“提取”K为了实例化mem,并对参数进行类型检查apply.

是不是要问很多? :) 我想写一些类似的东西

class ReducerComponent[KeyVal[K,V]](f: (V, V) => V) {...}

到时候我会实例化ReducerComponent我所拥有的就是f and MapOutput,所以推断 V 就可以了。但那时我只有KeyVal[K,V]作为类的类型参数,它可以不同于KeyVal[_,_].

我知道如果您了解类型推断的工作原理,我的要求可能很疯狂,但我不明白!我什至不知道什么是继续下去的好方法——除了在我的高级代码中一直进行显式类型声明之外。我应该改变所有的架构吗?


只需编写一个简单的工厂即可:

case class RC[M <: KeyVal[_, _]](){
   def apply[K,V](f: (V,V) => V)(implicit ev: KeyVal[K,V] =:= M) = new ReducerComponent[K,V](f)
}

def plus(x: Double, y: Double) = x + y

scala> RC[KeyVal[Int, Double]].apply(plus)
res12: ReducerComponent[Int,Double] = ReducerComponent@7229d116

scala> RC[KeyVal[Int, Double]]()(plus)
res16: ReducerComponent[Int,Double] = ReducerComponent@389f65fe

如你看到的,ReducerComponent有合适的类型。这里使用隐式证据来捕捉K and V从你的M <: KeyVal[_, _].

附:上面的版本需要明确指定参数类型f, like (_: Double) + (_: Double)。如果你想避免这种情况:

case class RC[M <: KeyVal[_, _]](){
   def factory[K,V](implicit ev: KeyVal[K,V] =:= M) = new {
      def apply(f: (V,V) => V) = new ReducerComponent[K,V](f)
   }
}

scala> RC[KeyVal[Int, Double]].factory.apply(_ + _)
res5: ReducerComponent[Int,Double] = ReducerComponent@3dc04400 


scala> val f = RC[KeyVal[Int, Double]].factory
f: AnyRef{def apply(f: (Double, Double) => Double): ReducerComponent[Int,Double]} = RC$$anon$1@19388ff6

scala> f(_ + _)
res13: ReducerComponent[Int,Double] = ReducerComponent@24d8ae83

更新。如果你想通用 keyval - 使用类型函数:

type KV[K,V] = KeyVal[K,V] //may be anything, may implement `type KV[K,V]` from some supertrait

case class RC[M <: KV[_, _]](){   
  def factory[K,V](implicit ev: KV[K,V] =:= M) = new {
    def apply(f: (V,V) => V) = new ReducerComponent[K,V](f)
  }
}

但请记住apply从你的问题来看还需要KeyVal[K,V].

您还可以通过KV进入某个班级:

class Builder[KV[_,_]] {
  case class RC[M <: KV[_, _]](){   
    def factory[K,V](implicit ev: KV[K,V] =:= M) = new {
      def apply(f: (V,V) => V) = new ReducerComponent[K,V](f)
    }
  }
}

scala> val b = new Builder[KeyVal]
scala> val f = b.RC[KeyVal[Int, Double]].factory
scala> f(_ + _)
res2: ReducerComponent[Int,Double] = ReducerComponent@54d9c993
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何“提取”类型参数来实例化另一个类 的相关文章

  • 选项包装值是一个好的模式吗?

    我最近写了以下 Scala 代码 val f File pretend this file came from somewhere val foo toFoo io Source fromFile f mkString 我真的不喜欢这种方式
  • 如何询问 Scala 类型参数的所有实例化是否存在证据?

    给定皮亚诺数的以下类型级加法函数 sealed trait Nat class O extends Nat class S N lt Nat extends Nat type plus a lt Nat b lt Nat a match c
  • Twitter Future 与 Scala Future 相比有何优势?

    我知道 Scala Future 变得更好的很多原因 有什么理由改用 Twitter Future 吗 除了 Finagle 使用它这一事实之外 免责声明 我在 Twitter 负责 Future 的实施 一点背景知识 在 Scala 有一
  • Scala - Java = ? (或者 Clojure - Java = ?)

    开发人员可以在不懂 Java 的情况下使用 Scala 吗 开发人员可以在不懂 Java 的情况下使用 Clojure 吗 注意 例如 我是一名 C 开发人员 我在不了解任何 VB 的情况下使用 NET 当然 WF 4 0 使用 VB 进行
  • 如何手动推断表达式的类型

    给定 Haskell 函数 head filter fst 现在的问题是如何手动 手动 找到类型 如果我让 Haskell 告诉我我得到的类型 head filter fst Bool b gt Bool b 但我想了解仅使用所用函数的签名
  • Scala Function.tupled 和 Function.untupled 等效于变量 arity,或者使用元组调用变量 arity 函数

    昨晚我试图围绕接受和调用通用函数做一些事情 即类型在调用站点上已知 但可能因调用站点而异 因此定义应该是跨参数通用的 例如 假设我有一个函数f A B C gt Z 其实这样的还有很多fs 我事先不知道 所以我无法确定类型或数量A B C
  • 用惯用的 Scala 更新大型数据结构

    我已经尝试 Scala 一段时间了 并且经常遇到支持不可变数据结构的建议 但是当你有一个像这样的数据结构时3D 场景图 大型神经网络或任何具有大量需要频繁更新的对象的东西 对场景中的对象进行动画处理 训练神经网络 这似乎是 运行时效率极低
  • ';'预期但发现“导入” - Scala 和 Spark

    我正在尝试使用 Spark 和 Scala 来编译一个独立的应用程序 我不知道为什么会收到此错误 topicModel scala 2 expected but import found error import org apache sp
  • 如何从字符串列中提取数字?

    我的要求是从列中的评论列中检索订单号comment并且总是开始于R 订单号应作为新列添加到表中 输入数据 code id mode location status comment AS SD 101 Airways hyderabad D
  • 通用 scala 函数,其输入是变量数量的函数

    我想定义一个函数f需要另一个函数g 我们需要g采取采取n双打 对于某些固定n 并返回一个 Double 函数调用f g 应该返回具体值n 例如 f Math max 2因为 Math sin 具有类型 Double Double gt Do
  • 为什么 Scala 中的隐式类必须驻留在另一个特征/类/对象中?

    基于scala文档 http docs scala lang org overviews core implicit classes html http docs scala lang org overviews core implicit
  • 如何在 Apache Spark 中通过 DStream 使用特征提取

    我有通过 DStream 从 Kafka 到达的数据 我想进行特征提取以获得一些关键词 我不想等待所有数据的到达 因为它是可能永远不会结束的连续流 所以我希望以块的形式执行提取 如果准确性会受到一点影响 对我来说并不重要 到目前为止 我整理
  • 如何从命令行向 REPL 添加导入?

    如何使 REPL 导入命令行中给出的包 Sample scala someMagicHere import sys error scala gt imports 1 import scala Predef 162 terms 78 are
  • 具有两个通用参数的上下文边界

    在 Scala 中 我可以使用上下文边界 def sort T Ordered t Seq T 与以下意思相同 def sort T t Seq T implicit def Ordered T 如果我有一个带有两个泛型参数的类怎么办 IE
  • Scala 宏的位置怎么了?

    我试图获取宏参数的原始输入字符串 但返回的位置似乎有点偏离 考虑这个宏 例如 object M import scala reflect macros Context import language experimental macros
  • 从 HList 获取元素

    我尝试了 HList 并按预期进行了以下工作 val hl 1 foo HNil val i Int hl 0 val s String hl 1 但是 我无法让以下代码正常工作 让我们暂时假设对列表进行随机访问是一个聪明的主意 class
  • 在 Spark MLlib 上使用 Java 中的 Breeze

    在尝试从Java使用MLlib时 使用微风矩阵运算的正确方法是什么 例如scala 中的乘法很简单 matrix vector 相应的功能在Java中是如何表达的 有一些方法 例如 colon times 可以通过正确的方式调用 breez
  • Scala:什么是 CompactBuffer?

    我试图弄清楚 CompactBuffer 的含义 和迭代器一样吗 请解释其中的差异 根据 Spark 的文档 它是 ArrayBuffer 的替代方案 可以提供更好的性能 因为它分配的内存更少 以下是 CompactBuffer 类文档的摘
  • 如何在映射中将字符串转换为 Seq[String]

    我有一个Map String String 以及需要的第三方功能Map String Seq String 有没有一种简单的方法来转换它 以便我可以将地图传递给函数 original mapValues Seq 注意mapValues返回地
  • Java 8 Stream,获取头部和尾部

    Java 8 引入了Stream http download java net jdk8 docs api java util stream Stream html类似于 Scala 的类Stream http www scala lang

随机推荐