Scala:在路径相关上下文中重用路径相关类型产生的泛型

2024-01-02

简而言之:以下内容无法编译(原因如下),我怎样才能使其工作?

trait Simulator {
  type CM[T]
  def useCM(v: CM[_])
}

case class CMH[S <: Simulator,T](cm: S#CM[T])

class SimIterator[S <: Simulator](val sim: S, val cmhs: Seq[CMH[S,_]]) {
  cmhs foreach { cmh => sim.useCM(cmh.cm) }
  /*
  compile time error:
   type mismatch; found : cmh.cm.type (with underlying type S#CM[_$2]) required:
   SimIterator.this.sim.CM[_] Note: _$2 <: Any (and cmh.cm.type <: S#CM[_$2]),
   but type CM is invariant in type T. You may wish to define T as +T instead.
   (SLS 4.5)
  */
}

该结构背后的想法是CMH hides T-具体行为来自SimIterator后者处理常见任务。S用于强制值CMH拥有正确的类型而无需实例Simulator.

In the foreach,似乎存在与以下相关的子类型问题CM. If S#CM是我们需要的具体类型sim.CM =:= S#CM。但是,请看以下内容:

object Test extends Simulator {
  type CM[T] = Option[T]
  def useCM(v: CM[_]) = println(v)
  def mkCM[T]: CM[T] = None

  CMH[Simulator,AnyRef](mkCM[AnyRef])
}

我们现在有一个CMH我们可以传递到SimIterator与任何一起Simulator。所以显然打字SimIterator限制不够。如何表达(和使用)S =:= sim.type?

UPDATE

这可以工作,但不能在构造函数中使用(非法依赖方法类型:参数出现在同一部分或较早部分中另一个参数的类型中)

class SimIterator(val sim: Simulator) {
  def doIt(cmhs: Seq[CMH[sim.type,_]]) {
    cmhs foreach { cmh => sim.useCM(cmh.cm) }
  }
}

上面的例子可以工作,但是not我想要的是。cmhs应在构造时传入。


您可以通过将抽象类型成员移动到类型参数来轻松解决该问题,如下所示:

trait Simulator[CM[_]] {
  def useCM(v: CM[_])
}

case class CMH[CM[_]](cm: CM[_])

class SimIterator[S <: Simulator[CM], CM[_]](val sim: S, val cmhs: Seq[CMH[CM]]) {
  cmhs foreach { cmh => sim.useCM(cmh.cm) }
}

这样您就可以避免使用类型投影,如果您确实需要将 CM 保留为类型成员,请提供更多详细信息,解释在哪种情况下您需要类型投影以及原因。

编辑/更新

欢迎来到“末日面包店”! ;-)

这种情况有两种解决方案:

1st, 把你的迭代器放进蛋糕里,因此您可以直接访问该类型:

case class CMH[CM[_]](cm: CM[_])

trait Cake {
  type CM[_]

  trait Simulator {
    def useCM(v: CM[_])
  }

  class SimIterator[S <: Simulator](val sim: S, val cmhs: Seq[CMH[CM]]) {
    cmhs foreach { cmh => sim.useCM(cmh.cm) }
  }
}

or 2nd, 将迭代器封装在另一个类中,使得访问路径相关类型成为可能:

trait Cake {
  type CM[_]

  trait Simulator {
    def useCM(v: CM[_])
  }
}

case class CMH[CM[_]](cm: CM[_])

class SimIteratorBuilder[C <: Cake](val cake: Cake) {
  class SimIterator(val sim: cake.Simulator, val cmhs: Seq[CMH[cake.CM]]) {
    cmhs foreach { cmh => sim.useCM(cmh.cm) }
  }
}

一旦陷入蛋糕,就无法逃脱!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala:在路径相关上下文中重用路径相关类型产生的泛型 的相关文章

随机推荐

  • 错误消息“操作正在进行中”是什么意思?

    当尝试使用以下命令打开文件时 fd fopen majestic files majestic record txt w 我收到以下错误消息 b Warning b fopen majestic files majestic record
  • 发生数据库错误错误号:1062

    我尝试使用 sql 为我的 CI 执行一次更新三个表的选项 但为什么它仍然错误 这是错误警告 A Database Error Occurred Error Number 1062 Duplicate entry 0 for key 1 U
  • 如何在java中重复播放音频文件

    我怎样才能让音频文件连续重复 现在音乐只播放一次 仅此而已 我试图让声音一遍又一遍地重复 我必须以其他方式获取音频文件还是有更简单的方法 Code import java io File import java io FileInputSt
  • Python 的 itertools.repeat 的目的是什么?

    对于我能想到的 Python 的每一种用途itertools repeat http docs python org py3k library itertools html highlight repeat itertools repeat
  • 如何让 Eclipse Oxygen 在 Java 9 上运行

    我拼命尝试让 Eclipse Oxygen 在 Mac OSX 上运行 Java 9 但似乎失败了 到目前为止我已经完成的步骤 在 Library Java JavaVirtualMachines jdk 9 jdk 中安装了 Java 9
  • Firebase 更新正在制作新的,除了最后一个字符外具有相同的 id

    我正在使用此代码来更新 Firebase 上的数据 但它会生成新的数据 我尝试了很多代码 除了最后一个字符之外 它使用相同的密钥制作新的代码 我按照 Firebase 网站的推荐使用了这个 但它不起作用 我创建了一个新的 下次更新时 Map
  • 检查 Bash 列表中是否存在变量

    我正在尝试在 bash 中编写一个脚本来检查用户输入的有效性 我想匹配输入 比如变量x 到有效值列表 我现在想出的是 for item in list do if x item then echo In the list exit fi d
  • iPad Safari (iOS 5.0.1) 上的 iframe CSS3 缩放问题

    我需要放大 iframe 以使其更大 我无法控制 iframe 内容的源代码 我正在尝试通过以下方式实现它 webkit transform scale 1 3 CSS 属性 iframe 的内容已正确放大 但是当我尝试触摸 iframe
  • Azure Functions DocumentClient 无法从程序集异常加载类型

    我有一个 Azure Function v2 它调用一个实用程序库 该库又实例化一个DocumentClient 当在本地运行我的函数时 它会在此行引发异常 client new DocumentClient new Uri cosmosD
  • 响应开头额外的未定义字符[重复]

    这个问题在这里已经有答案了 这阻止了我使用 JSON 也阻止了使用 React 或 Ember 使用 AJAX 向服务器发送请求时 我收到一个额外的未定义 unicode 字符 这会导致解析器错误 因为它破坏了 JSON 我已经检查了我拥有
  • 自动将公共更改为私有(Java)

    我正在对从其他语言翻译成 Java 的代码进行重构 我想自动完成它 我的问题是 我有很多不是私有的方法 但只是在声明它们的同一个类中调用 并且我想将它们设为私有 我有很多课程 我想是否有什么可以帮助我半自动地完成它 我想知道 你知道我是否可
  • .NET 中的并行抓取

    我工作的公司运营着数百个非常活跃的网站 它决定建立一个搜索引擎 我的任务是编写爬虫 一些网站在旧硬件上运行 无法承受太多惩罚 而另一些网站则可以处理大量并发用户 我需要能够说对站点 A 使用 5 个并行请求 对站点 B 使用 2 个并行请求
  • vtkRenderer 错误

    我是 vtk 的新手 所以我首先使用 CMake 和 Visual Studio 2017 构建 vtk 8 1 1 并使用默认选项和示例 许多示例运行良好 但其中一些会出现错误 这是 CreateTree 示例 但 HelloWorld
  • 无法使用 Gradle 6.1.1 解析 junit-jupiter-params:5.6.2 和 junit-jupiter-engine:5.6.2

    我有一个 Android 项目 其中包含 2 个 Android 模块和 1 个纯 Java 模块 将 android 构建工具更新为 com android tools build gradle 4 0 0 并将 gradle 包装器更新
  • 使用 OAuth2 将 JHipster 中的前端和 API 服务器分开不起作用

    我使用 OAuth2 创建了一个简单的 JHipster 6 2 0 Angular 应用程序 并且还单独生成了一个客户端应用程序 此外 我使用 keycloak yml 为 Keycloak 创建了一个 docker JHipster 附
  • 使用 for 循环在 ggplot2 中添加图层

    我想这很容易 但我不明白 它与 ggplots 上 for 循环的使用有关 问题是 为什么下面这两个代码给出不同的结果 看起来好像在带有循环的代码上 只考虑了第二次迭代 但我不知道为什么 根本问题是 是否可以使用 ggplot2 对象运行此
  • Android 数据存储 IOException 无法重命名为

    我正在尝试在我的项目中实现 Jetpack Datastore 我当时用的是apha 01版本和代码工作正常 然后我在Gradle文件中看到有新版本所以我将其更新为alpha 03 启动我的应用程序后 我遇到了另一个问题 我发现Proto库
  • 为什么我在 Android 上无法检测到带有 unicode 字符的 wifi SSID?

    我有一个 Wi Fi AP 其 SSID 是一串 unicode 字符 例如 我希望 Android 设备连接到它 当我的设备 Nexus One 检测到热点时 SSID 看起来像这样 并且无法识别它 知道如何解决这个问题吗 802 11数
  • Python数据结构按字母顺序排序列表[重复]

    这个问题在这里已经有答案了 我对 python 中的数据结构有点困惑 and 我正在尝试对一个简单的列表进行排序 可能是因为我无法识别数据的类型 所以无法对其进行排序 我的清单很简单 Stem constitute Sedge Eflux
  • Scala:在路径相关上下文中重用路径相关类型产生的泛型

    简而言之 以下内容无法编译 原因如下 我怎样才能使其工作 trait Simulator type CM T def useCM v CM case class CMH S lt Simulator T cm S CM T class Si