簡體   English   中英

為什么scala不推斷繼承特征的類型成員?

[英]Why doesn't scala infer the type members of an inherited trait?

我有一組類型,每個類型都有自己的類型成員:

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的集合上運行(使用樣板而不是抽象的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類型。 而且,我寧願不使用無形。 這是一個很棒的圖書館,但我不想把它拉進來解決這個問題。

通過聲明:

val schema: Schema

您指定該schema必須是Schema類型或其任何子類型 因此,了解schema的類型,您無法推斷Schema因為它可能是schema.type任何超類型

您可以通過完全顛倒事物來解決您的問題:根據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)
    }
}

(不確定它是否真的有效,但理論上這應該是檢查。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM