如何在Scala3/Dotty中实现像MapK这样的类型?

我正在尝试但未能让这样的东西在 Scala 3 中工作:

type TupleK[K[*], V[*], A] = (K[A], V[A]) 

final class MapK[K[*], V[*]] private (val rawMap: Map[K[?], V[?]]) {
    
  def foreach(f: TupleK[K, V, ?] => Unit): Unit = {
    rawMap.foreach(f.asInstanceOf[Tuple2[K[?], V[?]] => Any])
  }
}

object MapK {
  
  def apply[K[*], V[*]](entries: TupleK[K, V, ?]*): MapK[K, V] = {
    new MapK[K, V](Map(entries: _*))
  }
}

像这样使用:

class Key[A]()
  
type Id[A] = A
  
val intKey = Key[Int]
val strKey = Key[String]

MapK[Key, Id](intKey -> 1, strKey -> "a")

在 Scala 2 中,只需要通过替换*?使用来调整语法__*当然除外)。

然而,在 Scala 3 中,基本上每一行都会出现“无法将更高类型的类型应用于通配符参数”的错误:Scastie。

文档说Scala 3 中已经删除了存在类型,但是他们并没有真正给出任何关于如何处理这个问题的重要示例。

文档提到“存在类型与依赖路径的类型在很大程度上重叠”——这个 MapK 可以用依赖路径的类型来实现吗?我读过这个,但不明白如何应用它,或者在我的情况下是否可行。

而且,如果不是路径依赖类型……那又如何?Scala 似乎不太可能被“简化”到无法再实现此功能的地步,所以我一定遗漏了一些东西。

ETA:除了下面我自己的答案之外,我还制作了这个 repo并写了这篇关于在 Scala 3 中编码 MapK 的各种方法的文章。

以上是如何在Scala3/Dotty中实现像MapK这样的类型?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>