Dotty 无法推断采用抽象类型的类型参数特征的泛型 Scala 函数的结果类型

2023-12-13

简单的价值层次结构

想象一下这个简单的特征Value其中每个实现类都有一个value某种类型的T.

trait Value {
  type T
  def value: T
}

我们有两个不同的实现类代表Int and String值分别。

case class IntValue(override val value: Int) extends Value {
  override type T = Int
}

case class StringValue(override val value: String) extends Value {
  override type T = String
}

值的类型安全选择

如果我们有一个List对于值,我们希望有一种类型安全的方法来选择特定类型的所有值。班级Values及其伴随对象帮助我们做到这一点:

object Values {
  private type GroupedValues = Map[ClassTag[_ <: Value], List[Value]]

  def apply(values: List[Value]): Values = {
    val groupedValues: GroupedValues = values.groupBy(value => ClassTag(value.getClass))
    new Values(groupedValues)
  }
}

class Values private (groupedValues: Values.GroupedValues) {
  // Get a List of all values of type V.
  def getValues[V <: Value : ClassTag] = {
    val classTag = implicitly[ClassTag[V]]
    groupedValues.get(classTag).map(_.asInstanceOf[List[V]]).getOrElse(Nil)
  }

  def getValue[V <: Value : ClassTag] = {
    getValues.head
  }

  def getValueOption[V <: Value : ClassTag] = {
    getValues.headOption
  }

  def getValueInner[V <: Value : ClassTag] = {
    getValues.head.value
  }
}

所有这些在 Scala 2.13 和 Dotty 0.20.0-RC1 中都可以正常工作,因此有一个混合值列表......

val valueList = List(IntValue(1), StringValue("hello"))
val values = Values(valueList)

…我们可以选择元素并将它们作为正确的类型返回——所有这些都在编译时进行检查:

val ints: List[IntValue] = values.getValues[IntValue]
val strings: List[StringValue] = values.getValues[StringValue]

val int: IntValue = values.getValue[IntValue]
val string: StringValue = values.getValue[StringValue]

val intOption: Option[IntValue] = values.getValueOption[IntValue]
val stringOption: Option[StringValue] = values.getValueOption[StringValue]

val i: Int = values.getValueInner[IntValue]
val s: String = values.getValueInner[StringValue]

选择一个值作为Option[T]多蒂失败

但是,如果我们添加此函数来选择值作为它们的值T类型(即Int and String)并将其作为Option

class Values ... {
  ...
  def getValueInnerOption[V <: Value : ClassTag] = {
    getValues.headOption.map(_.value)
  }
}

…然后在 Scala 2.13 中一切正常:

val iOption: Option[Int] = values.getValueInnerOption[IntValue]
val sOption: Option[String] = values.getValueInnerOption[StringValue]

但在 Dotty 0.20.0-RC1 中,这无法编译:

-- [E007] Type Mismatch Error: getValue.scala:74:29 
74 |  val iOption: Option[Int] = values.getValueInnerOption[IntValue]
   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                             Found:    Option[Any]
   |                             Required: Option[Int]
-- [E007] Type Mismatch Error: getValue.scala:75:32 
75 |  val sOption: Option[String] = values.getValueInnerOption[StringValue]
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                                Found:    Option[Any]
   |                                Required: Option[String]

我们可以通过添加类型参数来解决这个问题getValueInnerOption将返回类型和抽象类型联系起来T在一起并允许我们指定返回类型。

def getValueInnerOption[V <: Value {type T = U} : ClassTag, U]: Option[U] = {
  getValues.headOption.map(_.value)
}

不幸的是,这意味着我们必须添加实际类型T (i.e Int or String)在调用站点,这很遗憾,因为它只是样板。

val iOption: Option[Int] = values.getValueInnerOption[IntValue, Int]
val sOption: Option[String] = values.getValueInnerOption[StringValue, String]

Dotty 中的错误或该怎么办?

看来 Dotty 已经知道了T是,但无法将该知识传播到函数的结果类型。如果试图要求一个String从一个IntValue:

-- [E057] Type Mismatch Error: getValue.scala:75:39 
75 |  val wtf = values.getValueInnerOption[IntValue, String]
   |                                       ^
   |Type argument IntValue does not conform to upper bound Value{T = String} 

原始代码也是如此(没有类型参数U)可以在最终的 Scala 3.0 中使用的东西还是需要以不同的方式编写?


在多蒂尝试匹配类型作为类型投影的替代品

type InnerType[V <: Value] = V match {
  case IntValue    => Int
  case StringValue => String
}

trait Value {
  type This >: this.type <: Value
  type T = InnerType[This]
  def value: T
}

case class IntValue(override val value: Int) extends Value {
  override type This = IntValue
}

case class StringValue(override val value: String) extends Value {
  override type This = StringValue
}

def getValueInner[V <: Value { type This = V } : ClassTag]: InnerType[V] = {
  getValues.head.value
}

def getValueInnerOption[V <: Value { type This = V } : ClassTag]: Option[InnerType[V]] = {
  getValues.headOption.map(_.value)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dotty 无法推断采用抽象类型的类型参数特征的泛型 Scala 函数的结果类型 的相关文章

  • 具有两个通用参数的上下文边界

    在 Scala 中 我可以使用上下文边界 def sort T Ordered t Seq T 与以下意思相同 def sort T t Seq T implicit def Ordered T 如果我有一个带有两个泛型参数的类怎么办 IE
  • Scala 的代码覆盖率工具 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 高效序列化案例类

    对于我正在工作的图书馆 我需要提供一个高效 便捷 typesafe序列化 scala 类的方法 理想的情况是用户可以创建一个案例类 并且只要所有成员都是可序列化的 它似乎也应该如此 我准确地知道序列化和反序列化阶段的类型 因此不需要 也不能
  • 具有上限的联合类型

    我正在遵循这个问题的公认答案中提出的技术如何定义 类型析取 联合类型 https stackoverflow com questions 3508077 does scala have type disjunction union type
  • 如何使用 Spark 2 屏蔽列?

    我有一些表 我需要屏蔽其中的一些列 要屏蔽的列因表而异 我正在读取这些列application conf file 例如 对于员工表如下所示 id name age address 1 abcd 21 India 2 qazx 42 Ger
  • 使用 net.liftweb.json 或 scala.util.parsing.json 解析大型 (30MB) JSON 文件会出现 OutOfMemoryException。有什么建议吗?

    我有一个包含大量测试数据的 JSON 文件 我想解析这些数据并推送我正在测试的算法 它的大小约为 30MB 包含大约 60 000 个元素的列表 我最初在 scala util parsing json 中尝试了简单的解析器 如下所示 im
  • Scala:什么是 CompactBuffer?

    我试图弄清楚 CompactBuffer 的含义 和迭代器一样吗 请解释其中的差异 根据 Spark 的文档 它是 ArrayBuffer 的替代方案 可以提供更好的性能 因为它分配的内存更少 以下是 CompactBuffer 类文档的摘
  • 在 Scala 中将元素追加到列表末尾

    我无法添加 type 元素T到一个列表中List T 我尝试过myList myElement但它似乎创建了一个奇怪的对象并访问myList last始终返回放入列表中的第一个元素 我怎么解决这个问题 List 1 2 3 4 Result
  • Slick和bonecp:org.postgresql.util.PSQLException:FATAL:抱歉,太多客户端已经错误

    当我在本地开发应用程序时 我使用以下命令启动我的 play2 应用程序sbt run 我喜欢如何更改代码 然后重新加载浏览器以查看我的更改 在大约 10 次代码更改之后 我收到 postgresql 太多连接错误 见下文 我的数据库连接使用
  • 解决“Show”类型类实例的隐式问题

    我正在努力使Gender实施Show类型类 scala gt trait Gender extends Show Gender defined trait Gender scala gt case object Male extends G
  • 具有继承类型的 Aux 模式推理失败

    我有一个复杂的玩具算法 我希望纯粹在类型级别上表示 根据饮食要求选择当天菜肴的修改 对卷积表示歉意 但我认为我们需要每一层才能达到我想要使用的最终界面 我的代码有一个问题 如果我们表达一个类型约束Aux 模式生成的类型基于另一个泛型类型 它
  • XML 创建 - 错误:带有替代方案的重载方法构造函数 UnprefixedAttribute

    scala gt val count 7 count Int 7 将其放入 XML 属性中会出现错误 scala gt val x
  • Spark scala 模拟 Spark.implicits 用于单元测试

    当尝试使用 Spark 和 Scala 简化单元测试时 我使用 scala test 和mockito scala 以及mockito Sugar 这只是让你做这样的事情 val sparkSessionMock mock SparkSes
  • 如何在不从 DataFrame 转换并访问它的情况下向数据集添加列?

    我知道使用以下方法将新列添加到 Spark 数据集的方法 withColumn and a UDF 它返回一个 DataFrame 我还知道 我们可以将生成的 DataFrame 转换为 DataSet 我的问题是 如果我们仍然遵循传统的
  • 如何在 Lift 框架中添加新页面

    如何在 lift 中的 webapp 目录中添加一个可供用户访问的新页面 目前只能通过index html访问http localhost 8080 com http localhost 8080 or http localhost 808
  • 火花内存不足

    我有一个文件夹 里面有 150 G 的 txt 文件 大约 700 个文件 平均每个 200 MB 我使用 scala 来处理文件并最终计算一些汇总统计数据 我认为有两种可能的方法可以做到这一点 手动循环所有文件 对每个文件进行计算并最终合
  • 了解 Spark 中的 DAG

    问题是我有以下 DAG 我认为当需要洗牌时 火花将工作划分为不同的阶段 考虑阶段 0 和阶段 1 有些操作不需要洗牌 那么为什么 Spark 将它们分成不同的阶段呢 我认为跨分区的实际数据移动应该发生在第 2 阶段 因为这里我们需要cogr
  • Spark:查找前 n 个值的高性能方法

    我有一个很大的数据集 我想找到具有 n 个最高值的行 id count id1 10 id2 15 id3 5 我能想到的唯一方法是使用row number没有分区就像 val window Window orderBy desc coun
  • 数量重新分配逻辑 - 具有外部数据集的 MapGroups

    我正在研究一种复杂的逻辑 需要将数量从一个数据集重新分配到另一个数据集 在例子中我们有Owner and Invoice 我们需要从数量中减去Invoice准确地Owner匹配 在给定汽车的给定邮政编码处 减去的数量需要重新分配回同一辆车出
  • 你能在 scala 中使用 varargs 柯里化一个函数吗?

    我正在考虑如何用可变参数柯里化一种方法 然后我意识到我什至不知道如何去做 理想情况下 它应该让您可以随时开始使用它 然后以可迭代结束 def concat strs String strs mkString val curriedConca

随机推荐

  • Heroku-18:Git 推送失败。在推送中显示不同版本的 Ruby

    如果这是一个愚蠢的问题 我很抱歉 我对Ruby一无所知 还尝试了SO的几种解决方案 成功升级 Ruby 解决依赖关系 现在只是卡住了 无法前进 任何帮助表示赞赏 谢谢 当我推送时 我得到了 ruby v2 2 2 但我刚刚升级到了 hero
  • angularjs 中重复的 ajax 调用

    我在用快递 jwt构建一个restful api 现在客户端正在进行重复的 ajax 调用 第一个调用的发起者是 angularjs 第二个调用的发起者是 other 第一个获取 204 作为响应代码 第二个获取 200 作为响应代码 我尝
  • SlowCheetah 在构建后事件后执行

    我使用 SlowCheetah 来转换我的 app configs 我有一个多项目解决方案 其中一个项目执行构建后事件 其中 bin 的输出被复制到其他地方 我发现 SlowCheetah 在构建后事件之后进行转换 因此我复制的 app c
  • 使用 C# 检查 Windows 7 上是否启用了 IPv6

    我正在尝试使用 C 编写一个程序作为我公司的多功能工具 我们希望在此工具中完成的一件事是确定 IPv6 是否已启用 绑定到我们的 Windows 7 计算机上的局域网连接网络适配器 我并不是在寻找它的地址 只是想知道它是否在该适配器上启用或
  • Silverlight 4 内存泄漏

    我有一个 Silverlight 4 应用程序 它有一个泄漏的 ViewModel 类 我已经通过在我的 ViewModel 类型上使用 WinDbg 和 gcroot 命令确认了这一点 我无法查明内存泄漏的确切原因 但尝试在关闭相应视图时
  • JpaRepository 上的 @PreAuthorize

    我希望为我的 REST 服务实现基于角色的安全性 我正在使用 spring data rest 并配置了JpaRepository像这样 Repository RestResource path changesets rel changes
  • ECDSA 和 ECDH 可用于单声道吗?

    这个问题几乎概括了这一点 ECDSA 和 ECDH 可用于单声道吗 如果不是 他们会吗 不 是他们无法使用Mono BCL 内部 也不是 Xamarin iOS 或 Xamarin Android 每个都有一个错误报告 ECDSA and
  • 是否可以同时显示新旧页面?

    我正在尝试为 smoothstate 建立这样的效果 http tympanus net Development PageTransitions 特别是 房间 过渡 我陷入尝试同时显示两个页面的困境 我希望新内容将旧内容推离屏幕 接下来是很
  • 我怎样才能在oracle中执行这个查询

    您能否指导我在 Oracle 中执行与此查询等效的操作 SELECT SQL CALC FOUND ROWS FROM tableName SELECT FOUND ROWS as cnt Thanks 对于 Oracle 9i 请使用 S
  • 抽象超类 scala 中的断言创建 NPE

    在 REPL 中输入以下代码 abstract class A val aSet Set Int require aSet contains 3 class B extends A val aSet Set 4 5 6 new B 给出一个
  • MatLab 函数将点从最大或最小点向左或向右移动

    我试图找出一个函数 该函数将找到一个距离我在 matlab 数组中设置的最小值和最大值 x 个点的点 可以说我愿意max data row 1 row 2 column 这给了我一个观点 我想找到对应于该值左侧和右侧 4 个点的值 所以可以
  • 在 iphone-sdk 中获取 facebook 点赞数

    我不想显示 喜欢 按钮 我只想获取特定链接被喜欢的计数 只需继续 没有 喜欢 按钮 没有对话 没有 只需对 Graph API 执行一个简单的 url 请求即可 http graph facebook com FULL URL Exampl
  • 将 pandas DataFrame 写入 CSV 文件

    我在 pandas 中有一个数据框 我想将其写入 CSV 文件 我正在使用以下方法执行此操作 df to csv out csv 并出现以下错误 UnicodeEncodeError ascii codec can t encode cha
  • elf 头中的 p_align 是什么?

    我正在学习逆向工程 readelf something Program Headers Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000040 0x00000
  • XTS 替换错误 NextMethod(.Generic):要替换的项目数

    我现在正在与 xts 作斗争 我有一个 XTS 对象 并且我正在尝试用新的集合替换特定日期的数据 但我不断遇到替换长度的问题 即使我确信它们是相同且无缺失数据 有任何想法吗 我做了一个虚拟示例来演示我的问题 R gt test1 xts c
  • javascript 在 IE 中很慢,但在 Firefox 中很快

    使用 IE 访问此页面非常慢 但使用 Firefox 访问速度要快得多 特别是当我增加人的节点数量时 任何想法有什么问题吗 http thejit org static v20 Jit Examples RGraph example1 ht
  • sql 将空值替换为其他列中的值

    我想将所有具有 NULL 值的值替换为同一行另一列中的值 我尝试过不同的sql语句 但没有成功 Regards 如果您想更新 请执行以下操作 update t set col1 col2 where col1 is null 如果您只想进行
  • 查询获取父记录和子记录,然后是mysql中的下一个父子记录

    我在以下格式的数据Names数据库中的表 ID Name ParentID 1 Parent 1 0 2 Parent 2 0 3 Parent 1 Child 1 1 4 Parent 2 Child 1 2 5 Parent 1 Chi
  • Google Maps API v2 ScrollView 内的 SupportMapFragment - 用户无法垂直滚动地图

    我试图将 Google 地图放入滚动视图中 以便用户可以向下滚动其他内容来查看地图 问题是这个滚动视图吞噬了所有垂直触摸事件 因此地图的 UI 体验变得非常奇怪 我知道在谷歌地图的V1中 您可以覆盖onTouch或setOnTouchLis
  • Dotty 无法推断采用抽象类型的类型参数特征的泛型 Scala 函数的结果类型

    简单的价值层次结构 想象一下这个简单的特征Value其中每个实现类都有一个value某种类型的T trait Value type T def value T 我们有两个不同的实现类代表Int and String值分别 case clas