gpt4 book ai didi

scala - 如果 bound 是抽象类型成员,则具有上限的更高种类的类型构造函数不起作用

转载 作者:行者123 更新时间:2023-12-01 00:20:21 26 4
gpt4 key购买 nike

我想定义一个由上限参数化的特征 R和更高种类的构造函数F[_]只接受 R 的子类型的参数.我希望这个特征实现多态 apply可以转换任何 F[A]进入 Unit ,前提是 A <: R .

这段代码工作得很好:

import scala.language.higherKinds

// this is the trait with polymorphic `apply`
trait CoCone[R, F[_ <: R]] {
def apply[A <: R](x: F[A]): Unit
}

// Example:
sealed trait Domain
class Dom1 extends Domain

class Fnctr[X <: Domain]

val c = new CoCone[Domain, Fnctr] {
def apply[D <: Domain](x: Fnctr[D]): Unit = ()
}

(见下文关于命名的备注)

现在,如果我抽象出 R通过将其声明为某个模块的类型成员,并定义 Fnctr[A <: R]在这个模块里面,像这样:
import scala.language.higherKinds

trait CoCone[R, F[_ <: R]] {
def apply[A <: R](x: F[A]): Unit
}

trait ModuleIntf {
type AbstractDomain
class Fnctr[X <: AbstractDomain]
}

// No mention of an actual concrete `Domain` up to
// this point. Now let's try to implement a concrete
// implementation of `ModuleIntf`:

sealed trait Domain
class Dom1 extends Domain

object ModuleImpl extends ModuleIntf {
type AbstractDomain = Domain
val c = new CoCone[Domain, Fnctr] { // error [1], error [2]
def apply[D <: Domain](x: Fnctr[D]): Unit = ()
}
}

一切都中断了,我收到两条我不知道如何解释的错误消息:
[1] error: kinds of the type arguments (Domain,Main.$anon.ModuleImpl.Fnctr) do not 
conform to the expected kinds of the type parameters (type R,type F) in trait CoCone.
Main.$anon.ModuleImpl.Fnctr's type parameters do not match type F's expected parameters:
type X's bounds <: ModuleIntf.this.AbstractDomain are stricter than type _'s declared bounds <: R
val c = new CoCone[Domain, Fnctr] {
^

[2] error: kinds of the type arguments (Domain,Main.$anon.ModuleImpl.Fnctr) do not
conform to the expected kinds of the type parameters (type R,type F) in trait CoCone.
Main.$anon.ModuleImpl.Fnctr's type parameters do not match type F's expected parameters:
type X's bounds <: ModuleIntf.this.AbstractDomain are stricter than type _'s declared bounds <: R
val c = new CoCone[Domain, Fnctr] {
^

我希望编译器会在 ModuleImpl 内部识别在 CoCone[Domain, Fnctr]所有三个 Domain = AbstractDomain = R是同一类型。

我在这里遗漏了什么明显的东西,还是 scalac 的限制? 2.12.4 ?如果这是一个限制,有人曾经在任何地方报告过吗?

编辑 找到类似的东西: issue #10186 .是“一样的”吗?不一样”?如果它是一个错误,我应该将它作为另一个测试用例提出吗?如果有人可以确认这不完全是我的错,和/或确实与相关问题密切相关,那将是问题的可接受解决方案。

编辑2 :正如@Evgeny 所指出的,它不能完全是问题10186,因为它在不同的编译器阶段失败( refchecks 而不是 typer )。

关于名称的备注:我已将特征称为 CoCone在这里,类比一般定义的 ~>这可以被认为是一种自然的转变。在某种程度上, CoCone[Dom, Fctr]类似于 Fctr ~> Const_Unit , 但域为 F仅限于 Dom 的子类型.实际上, CoCone[R, F]是有形的东西 F可以发送 R 的某些子类通过网络,但这并不重要,所以我已经抽象了名称。这东西是一个比较普通的数学结构,没什么做作的,如果能编译出来就好了。

最佳答案

使用抽象类型成员的工作方法(尝试使用 scalac 2.12.4):

import scala.language.higherKinds

trait CoCone[R, F[_ <: R]] {
def apply[A <: R](x: F[A]): Unit
}

trait ModuleIntf {
type AbstractDomain
type X = ({type XX <: AbstractDomain; type XXX = XX with AbstractDomain})
class Fnctr[X]
}

sealed trait Domain

case class Dom1() extends Domain

object ModuleImpl extends ModuleIntf {
type AbstractDomain = Domain
val f = new Fnctr[Dom1]()
val c = new CoCone[Domain, Fnctr] {
def apply[X](x: Fnctr[X]): Unit = ()
}
c(f)
}

想法取自 issue #4745 的评论.如果我没有遗漏任何东西,这应该等同于原始的不可编译方法。

正如我发现当前问题编译在不同编译器阶段( refchecks )时失败 #10186typer 上失败,但无论如何,在 #10186提到补丁,我试过了,它本身修复了#10186,但仍然报告当前错误。

我会说它应该编译,但我没有发现任何与当前问题相似的问题,所以,假设它还没有报告编译器错误。

在@Andrey 评论后更新。

是的,太专注于获得可编译的版本并且失去了特质的上限。对不起。

在深入了解编译器内部后更新

我调试了一些验证更高种类的类型( scala.reflect.internals.Kinds 大约 checkKindBoundsHK )并且看起来像在检查 Fnctr边界,绑定(bind)类型树中没有 AbstractDomain 的信息是 Domain 的别名.如果我将 CoCone 第一种类型更改为 AbstractDomainobject ,而不是在树中我看到它是 Domain ,但不适用于 Fnctr界限。

顺便说一句,修复 #10186试图解决类似的问题,评估绑定(bind)参数 asSeenFrom ,据我所知,试图获得具体类型,但在我们的例子中,树中没有关于具体类的内容, AbstractDomain被退回了。。

关于scala - 如果 bound 是抽象类型成员,则具有上限的更高种类的类型构造函数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49212454/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com