我正在努力学习Scala中的类型编程,我发现大多数关于类型编程需要知道的东西在价值编程中都有类似的对应,如{{3}中所反映的那样。 }。但是,我没有找到this
关键词或自我类型的类比。我怀疑期待这样的事情可能没有意义,但我想我会问。
例如,我可以编写以下内容在运行时将布尔值表示为值:
sealed trait BoolVal {
def not:BoolVal
def or(that:BoolVal):BoolVal
def and(that:BoolVal) =
(this.not or that.not).not
def imp(that:BoolVal) =
this.not or that
}
case object TrueVal extends BoolVal {
override val not = FalseVal
override def or(that:BoolVal) = TrueVal
}
case object FalseVal extends BoolVal {
override val not = TrueVal
override def or(that:BoolVal) = that
}
我的and
和imp
能够利用这一事实,如果我是一个假对象或一个正确定义的真实对象,这无关紧要。我的TrueVal
和FalseVal
对象可以继承相同的代码。
我可以制作类似的类型级编程结构,但我不明白如何在我的基本特征中定义And
和Imp
。
sealed trait BoolType {
type Not <: BoolType
type Or[That <: BoolType] <: BoolType
type And[That <: BoolType] = ???
type Imp[That <: BoolType] = ???
}
sealed trait TrueType extends BoolType {
override type Not = FalseType
override type Or[That <: BoolType] = TrueType
}
sealed trait FalseType extends BoolType {
override type Not = TrueType
override type Or[That <: BoolType] = That
}
我可以看到我的类型继承类型可能没有意义,但肯定会继承抽象类型。有没有办法在我的And
中定义Impl
和BoolType
,还是必须在相应的TrueType
和FalseType
特征中定义每个?
答案 0 :(得分:10)
您始终可以在布尔基类型上定义抽象类型,如下所示:
trait MyBool extends BoolType{
type This <: BoolType
}
trait TrueType extends BoolType{
type This = TrueType
}
你应该善于引用自己。然后您可以使用DeMorgan的法律来执行以下操作
!(x && y) == (!x || !y)
然后通过双重否定,你可以得到And
条件:
!(!x || !y) == !!(x && y) == (x && y)
答案 1 :(得分:9)
我建议您使用self
,调整博客文章的示例:
sealed trait BoolType { self =>
type Not <: BoolType
type Or[That <: BoolType] <: BoolType
type And[That <: BoolType] = self.type#Not#Or[That#Not]#Not
type Imp[That <: BoolType] = self.type#Not#Or[That]
}
sealed trait TrueType extends BoolType {
override type Not = FalseType
override type Or[That <: BoolType] = TrueType
}
sealed trait FalseType extends BoolType {
override type Not = TrueType
override type Or[That <: BoolType] = That
}
答案 2 :(得分:3)
为什么不使用this
关键字?当我自己探索类型级编程时,在使用它而不是self时我看不出有什么区别。
sealed trait BoolType {
type Not <: BoolType
type Or[That <: BoolType] <: BoolType
type And[That <: BoolType] = this.type#Not#Or[That#Not]#Not
type Imp[That <: BoolType] = this.type#Not#Or[That]
}