gpt4 book ai didi

scala - 为什么 Scala 不推断继承特征的类型成员?

转载 作者:行者123 更新时间:2023-12-01 11:38:19 25 4
gpt4 key购买 nike

我有一组类型,每个类型都有自己的类型成员:

sealed trait FieldType {
type Data
def parse(in: String): Option[Data]
}
object Name extends FieldType {
type Data = String
def parse(in: String) = Some(in)
}
object Age extends FieldType {
type Data = Int
def parse(in: String) = try { Some(in.toInt) } catch { case _ => None }
}

我有一组类型对 FieldType 的集合进行操作(使用样板而不是对元数进行抽象):

sealed trait Schema {
type Schema <: Product
type Data <: Product
val schema: Schema
def read(in: Seq[String]): Option[Data]
}
trait Schema1 extends Schema {
type D1
type FT1 <: FieldType { type Data = D1 }
type Schema = Tuple1[FT1]
type Data = Tuple1[D1]
def read(in: Seq[String]) = schema._1.parse(in(0)).map(Tuple1.apply)
}
trait Schema2 extends Schema {
type D1
type D2
type FT1 <: FieldType { type Data = D1 }
type FT2 <: FieldType { type Data = D2 }
type Schema = (FT1, FT2)
type Data = (D1, D2)
def read(in: Seq[String]) = {
for {
f <- schema._1.parse(in(0))
s <- schema._2.parse(in(1))
} yield (f, s)
}
}

我想我可以使用这个系统来优雅地定义有意义的字段集,因为 scala 将能够推断类型成员:

class Person extends Schema2 {
val schema = (Name, Age)
}

但是,这不能编译!我必须包括所有类型成员的定义:

class Person extends Schema2 {
type D1 = String; type D2 = Int
type FT1 = Name.type; type FT2 = Age.type
val schema = (Name, Age)
}

为什么 scala 不能推断 D1,... 和 FT1,...?我该如何重构它,这样我就不必在 Person 中指定类型变量?

注意:一旦我对宏有了更好的理解,我打算将它们用于 Schema 类型。另外,我宁愿不使用 shapeless。这是一个很棒的库,但我不想把它拉进来解决这个问题。

最佳答案

通过声明:

val schema: Schema

您指定schema 必须是Schema 类型或其任何子类型。因此,知道 schema 的类型后,您无法推断出 Schema,因为它可能是 schema.type 的任何父类(super class)型 .

您可以通过完全颠倒来解决您的问题:根据 schema.type 定义类型别名:

trait Schema2 extends Schema {
type Schema = (FieldType, FieldType)
type FT1 = schema._1.type
type FT2 = schema._2.type
type D1 = FT1#Data
type D2 = FT2#Data
type Data = (D1, D2)
def read(in: Seq[String]) = {
for {
f <- schema._1.parse(in(0))
s <- schema._2.parse(in(1))
} yield (f, s)
}
}

(不确定它实际上是否有效,但理论上这应该进行类型检查。)

关于scala - 为什么 Scala 不推断继承特征的类型成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24983882/

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