【发布时间】:2014-07-27 17:59:10
【问题描述】:
我有一组类型,每个类型都有自己的类型成员:
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 }
}
而且我有一组在 FieldTypes 集合上运行的类型(使用样板文件而不是对 arity 进行抽象):
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 类型。另外,我宁愿不使用无形。这是一个很棒的库,但我不想把它拉进来解决这个问题。
【问题讨论】:
-
这可能是结构类型的类型推断的限制吗?您是否尝试过改用泛型进行重组?
-
这确实适用于
FieldType上的泛型。但是,在字段类型上使用通用参数会使FieldType的工作变得非常混乱。我尝试将FieldType分为两种类型:FieldType和Parses[Data],但是编译器无法再次进行推理。
标签: scala scala-2.10