编译时间检查一些属性(Compile time check on some property)

编程入门 行业动态 更新时间:2024-10-24 20:17:26
编译时间检查一些属性(Compile time check on some property)

给出以下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): B

That 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@67d9a642

To "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 = true

You 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.

更多推荐

本文发布于:2023-07-23 12:04:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1231672.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:属性   时间   Compile   property   check

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!