Yan*_*san 1 type-systems scala
我尝试用抽象类型定义类型约束。但不幸的是,它无法编译。
sealed trait MatchableValue {
type A
def value: A
def asSingleItemValue : ItemValue
}
sealed trait ItemValue {
type A
def value: A
}
case class StringValue(value: String) extends ItemValue {type A = String}
case class StringMatchableValue(value: String) extends MatchableValue{
type A = String
override def asSingleItemValue = StringValue(value)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用
def asSingleItemValue[B <: ItemValue](implicit ev: A =:= B#A) : B
Run Code Online (Sandbox Code Playgroud)
类型约束的目的是在编译时警告此类错误:
case class IntValue(value: Int) extends ItemValue {type A = Int}
case class IntMatchableValue(value: Int) extends MatchableValue{
type A = Int
def asSingleItemValue = StringValue("error")
}
Run Code Online (Sandbox Code Playgroud)
您可以通过类型细化来完成此操作(请注意方法的返回类型):
sealed trait MatchableValue { self =>
type A
def value: A
def asSingleItemValue: ItemValue { type A = self.A }
}
sealed trait ItemValue {
type A
def value: A
}
case class StringValue(value: String) extends ItemValue { type A = String }
case class IntValue(value: Int) extends ItemValue { type A = Int }
Run Code Online (Sandbox Code Playgroud)
现在编译:
case class StringMatchableValue(value: String) extends MatchableValue {
type A = String
def asSingleItemValue = StringValue(value)
}
Run Code Online (Sandbox Code Playgroud)
但这不是:
case class StringMatchableValue(value: String) extends MatchableValue {
type A = String
def asSingleItemValue = IntValue(1)
}
Run Code Online (Sandbox Code Playgroud)
我相信这就是您想要的。
还值得注意的是,以下是处理类型细化时的常见模式:
sealed trait MatchableValue { self =>
type A
def value: A
def asSingleItemValue: ItemValue.Aux[A]
}
sealed trait ItemValue {
type A
def value: A
}
object ItemValue {
type Aux[A0] = ItemValue { type A = A0 }
}
Run Code Online (Sandbox Code Playgroud)
这确实做同样的事情,但是如果您发现自己需要大量写出类型细化的内容,那么语法是一个不错的选择。