F界多态类型和非泛型子类型的现有类型? [英] Existential types for F-Bounded Polymorphic types and non-generic subtypes?

查看:121
本文介绍了F界多态类型和非泛型子类型的现有类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个子类型,需要通过类型A进行F绑定多态,并且需要这些子类型之一的子类型,即

I have two subtypes that I need to be F-bounded polymorphic by a type A, and a subtype of one of those subtypes, i.e.

trait A[T <: A[T]] {
  def x: T
}
trait Ter extends A[Ter]
trait For extends A[For]
trait C extends Ter

接下来,我尝试实现一种具体类型

Next I try to implement a concrete type

case class F2(l: List[A[_]]) extends For {
  def x: For = F2(l.map(_.x))
}

但这无法编译为:

<console>:11: error: type mismatch;
 found   : List[Any]
 required: List[A[_]]
         def x: For = F2(l.map(_.x))
                              ^

所以,谷歌说我需要使用存在性类型,这很有意义,所以我尝试:

So, google says I need to use existential types, which makes sense, so I try:

import scala.language.existentials

type SomeA = T forSome { type T <: A[T] }

case class F1(l: List[SomeA]) extends For {
  def x: For = F1(l.map(_.x))
}

但是,现在我尝试实例化时遇到了一个新问题

But, now I face a new problem when I try to instantiate

trait Example {
  val b: Ter
  val c: C
  val d: For

  // Works fine
  val l1: List[A[_]] = List(b, c, d)
  // But this doesn't work, fails to compile (see below)
  val l2: List[SomeA] = List(b, c, d)

  val f1 = F1(l2)
}

编译错误:

<console>:22: error: type mismatch;
 found   : C
 required: SomeA
    (which expands to)  T forSome { type T <: A[T] }
         val l2: List[SomeA] = List(b, c, d)
                                       ^

为什么会出现此错误?当然CTer的子类型,又是A[Ter]的子类型,因此CA[Ter]的子类型,因此存在TTer,使得A[T]的子类型,因此CSomeA的子类型.

Why do I get this error? Surely C is a subtype of Ter, which in turn is a subtype of A[Ter], therefore C is a subtype of A[Ter], therefore there exists a T namely Ter such that C is a subtype of A[T], therefore C is a subtype of SomeA.

好像子类型的可传递性不起作用.当我用c.asInstanceOf[SomeA]对其进行破解时,我的代码会编译并且我的单元测试会通过.可能是编译器错误吗?

It's as if the transitivity of subtyping isn't working. When I hack it with c.asInstanceOf[SomeA] my code compiles and my unit tests pass. Could it be a compiler bug?

我还认为List[A[_]]的键入比List[SomeA]更强,即前者说列表由A[T]固定的 类型T组成,后者则说列表由A[T]组成,其中T不固定.

I also thought that List[A[_]] was stronger typing than List[SomeA], i.e. the former was saying the list consists of A[T] some fixed type T, where the latter is saying the list consists of A[T] where T is not fixed.

BOUNS (BOUNS )如果您可以解释为什么为什么当前接受的答案有效,即为什么编译器在没有归属的情况下无法确定该类型是否有效.

BOUNS If you can explain why the currently accepted answer works, i.e. why the compiler cannot work out that the type is valid without the ascription.

推荐答案

我想编译器需要一些帮助.以下应该可以工作:

I guess the compiler needs some help. The following should work:

val l2 = List[SomeA](b, c: Ter, d)

这篇关于F界多态类型和非泛型子类型的现有类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆