给出以下scala代码:
sealed trait Color case object Red extends Color case object Blue extends Color sealed trait Car { def isBroken: Boolean def color: Color }我如何定义这种方法:
def fixBrokenRedCar(c: A): B也就是说, A和B应该是什么? 该方法应该只接受一个既Red又isBroken = true 。 否则它应该会发出编译错误。 此外,输出B应包含其类型的信息,以便如果我创建另一个方法destroyRedCar(c: B)并将其应用于输出,则应相应地进行编译。
Given the following scala code:
sealed trait Color case object Red extends Color case object Blue extends Color sealed trait Car { def isBroken: Boolean def color: Color }How can I define such a method:
def fixBrokenRedCar(c: A): BThat is, what should A and B be? The method should only accept a Car that is both Red and isBroken = true. Otherwise it should emit a compile error. Moreover, the output B should contain information on its type such that if I create another method destroyRedCar(c: B) and apply it on the output, it should compile accordingly.
最满意答案
您应该将数据移动到类型级别:
trait Bool trait T extends Bool trait F extends Bool trait Color trait Red extends Color trait Blue extends Color trait Car[Clr <: Color, Brkn <: Bool] def fixBrokenCar[Cr <: Car[Red, T]](c: Cr) = new Car[Red, F]{} scala> fixBrokenCar(new Car[Blue, T]{}) <console>:16: error: inferred type arguments [Car[Blue,T]] do not conform to method fixBrokenCar's type parameter bounds [Cr <: Car[Red,T]] fixBrokenCar(new Car[Blue, T]{}) ^ <console>:16: error: type mismatch; found : Car[Blue,T] required: Cr fixBrokenCar(new Car[Blue, T]{}) ^ scala> fixBrokenCar(new Car[Red, T]{}) res3: Car[Red,F] = $anon$1@67d9a642为了“销毁”它:
def destroyRedCar(c: Car[Red, _]) = true scala> destroyRedCar(fixBrokenCar(new Car[Red, T]{})) res10: Boolean = true scala> destroyRedCar(new Car[Red, T]{}) res11: Boolean = true scala> destroyRedCar(new Car[Blue, T]{}) <console>:15: error: type mismatch; found : Car[Blue,T] required: Car[Red, ?] destroyRedCar(new Car[Blue, T]{}) ^如果你需要“改变” Cr类型(更精确地说构造一种类型):
trait Car[Clr <: Color, Brkn <: Bool] { type Copy[C <: Color, B <: Bool] <: Car[C,B] // define "copy" type-method } trait BrandedCar[Clr <: Color, Brkn <: Bool] extends Car[Clr, Brkn] { type Copy[C <: Color, B <: Bool] = BrandedCar[C, B] // implement "copy" type-method def brand: String = "default" } def fixBrokenCar[Cr <: Car[Red, T]](c: Cr) = c.asInstanceOf[Cr#Copy[Red, F]] def checkBrandedCar(c: BrandedCar[_, F]) = true // accepts only branded and fixed scala> checkBrandedCar(new BrandedCar[Red, F]{}) res10: Boolean = true scala> checkBrandedCar(new Car[Red, F]{}) <console>:15: error: type mismatch; found : Car[Red,F] required: BrandedCar[?, F] checkBrandedCar(new Car[Red, F]{}) ^ scala> checkBrandedCar(fixBrokenCar(new BrandedCar[Red, T]{})) res12: Boolean = true你也可以定义一些def copy[C <: Color, B <: Bool]: Copy[C, B]在Car的特征中def copy[C <: Color, B <: Bool]: Copy[C, B]方法(比如在类的情况下),而不仅仅是asInstanceOf 。
You should move your data to the type-level then:
trait Bool trait T extends Bool trait F extends Bool trait Color trait Red extends Color trait Blue extends Color trait Car[Clr <: Color, Brkn <: Bool] def fixBrokenCar[Cr <: Car[Red, T]](c: Cr) = new Car[Red, F]{} scala> fixBrokenCar(new Car[Blue, T]{}) <console>:16: error: inferred type arguments [Car[Blue,T]] do not conform to method fixBrokenCar's type parameter bounds [Cr <: Car[Red,T]] fixBrokenCar(new Car[Blue, T]{}) ^ <console>:16: error: type mismatch; found : Car[Blue,T] required: Cr fixBrokenCar(new Car[Blue, T]{}) ^ scala> fixBrokenCar(new Car[Red, T]{}) res3: Car[Red,F] = $anon$1@67d9a642To "destroy" it:
def destroyRedCar(c: Car[Red, _]) = true scala> destroyRedCar(fixBrokenCar(new Car[Red, T]{})) res10: Boolean = true scala> destroyRedCar(new Car[Red, T]{}) res11: Boolean = true scala> destroyRedCar(new Car[Blue, T]{}) <console>:15: error: type mismatch; found : Car[Blue,T] required: Car[Red, ?] destroyRedCar(new Car[Blue, T]{}) ^If you need to "mutate" Cr type (construct one type from another, more precisely):
trait Car[Clr <: Color, Brkn <: Bool] { type Copy[C <: Color, B <: Bool] <: Car[C,B] // define "copy" type-method } trait BrandedCar[Clr <: Color, Brkn <: Bool] extends Car[Clr, Brkn] { type Copy[C <: Color, B <: Bool] = BrandedCar[C, B] // implement "copy" type-method def brand: String = "default" } def fixBrokenCar[Cr <: Car[Red, T]](c: Cr) = c.asInstanceOf[Cr#Copy[Red, F]] def checkBrandedCar(c: BrandedCar[_, F]) = true // accepts only branded and fixed scala> checkBrandedCar(new BrandedCar[Red, F]{}) res10: Boolean = true scala> checkBrandedCar(new Car[Red, F]{}) <console>:15: error: type mismatch; found : Car[Red,F] required: BrandedCar[?, F] checkBrandedCar(new Car[Red, F]{}) ^ scala> checkBrandedCar(fixBrokenCar(new BrandedCar[Red, T]{})) res12: Boolean = trueYou may also define some def copy[C <: Color, B <: Bool]: Copy[C, B] method inside Car's trait (like in case classes) instead of just asInstanceOf.
更多推荐
发布评论