【问题标题】:Curried type "does not take type parameters"柯里化类型“不带类型参数”
【发布时间】:2021-01-31 05:30:08
【问题描述】:

我想创建一种可以用来验证元组是否同质的类型。我写了这个,应该保证T的所有元素都等于XScastie):

type Homogenous[X] = [T <: Tuple] =>> T match {
  case EmptyTuple => DummyImplicit
  case X *: t => Homogenous[X][t] //Doesn't work
  case _ => Nothing
}

def f[T <: Tuple : Homogenous[String]](t: T) = ???

由于某种原因,第三行无法编译,出现以下错误:

Homogenous[X] 不带类型参数

但是,如果我让 Homogenous 接受 2 个参数,它会编译,但我不能再使用上下文绑定 (Scastie)。

type Homogenous[X, T <: Tuple] = T match {
  case EmptyTuple => DummyImplicit
  case X *: t => Homogenous[X, t]
  case _ => Nothing
}

我不明白为什么会这样。并不是说 lambda [T] =&gt;&gt; 只是从匹配类型的特定情况下返回,所以编译器应该意识到 Homogenous[X] 总是带一个参数。这是一个错误还是我做错了什么,是否有修复/解决方法?

【问题讨论】:

  • 这在某种程度上是意料之中的。当你有一个递归函数时,你总是必须先声明它,然后在定义中调用它,比如val f = (a:Int) =&gt; (b:Int) =&gt; f(a)(b) 将不起作用,因为它在编译时不知道 f 类型是什么,它不能进行类型推导和同时定义。所以你需要做val f: Int=&gt;Int=&gt;Int = a =&gt; b =&gt; f(a)(b) 让它工作。但是对于类型定义,dotty 不允许在同一行声明(绑定)和定义,因此编译器不知道 Homogenous 是一个柯里化类型构造函数,因此您会看到错误。
  • @texasbruce 好点。但我想这还不是全部,因为type U &lt;: [T] =&gt;&gt; Any 允许使用U[Int] 类型,但如果我们在案例中添加上限type Homogenous[X] &lt;: ([T &lt;: Tuple] =&gt;&gt; Any) = [T &lt;: Tuple] =&gt;&gt; T match { ... 仍然无法编译。我怀疑这也可能是匹配类型如何转换为Matchdotty.epfl.ch/docs/reference/new-types/…
  • @texasbruce “但对于类型定义,dotty 不允许声明(绑定)和定义在同一行” 对于匹配类型的上限和定义是允许的。见代码 sn-p type Concat[Xs &lt;: Tuple, +Ys &lt;: Tuple] &lt;: Tuple = Xs match {... dotty.epfl.ch/docs/reference/new-types/match-types.html
  • @DmytroMitin 是的。看起来只有当 rhs 不是带有 match 子句的高阶类型时,才允许同时进行类型边界和定义。相当奇怪的要求。
  • @texasbruce 好吧,正如我在回答中提到的,多个类型参数列表未实现。也许type Homogenous[X][T &lt;: Tuple] = T match {...type Homogenous = [X] =&gt;&gt; [T &lt;: Tuple] =&gt;&gt; T match {... 会编译。

标签: scala types scala-3 dotty match-types


【解决方案1】:

看起来像一个错误或未充分实现的功能。

作为一种解决方法尝试

trait Hom[X] {
  type Rec[T <: Tuple] = T match {
    case EmptyTuple => DummyImplicit
    case X *: t => Rec[t] 
    case _ => Nothing
  }
}

type Homogenous[X] = [T <: Tuple] =>> Hom[X]#Rec[T]

可能与

有关

https://contributors.scala-lang.org/t/multiple-type-parameter-lists-in-dotty-si-4719

https://github.com/scala/bug/issues/4719

【讨论】:

  • 啊,太糟糕了。我会等一会儿,然后在 GitHub 上打开一个问题。
猜你喜欢
  • 2019-05-21
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
  • 2023-03-03
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多