scala types metaprogramming

¿Cuál es la analogía de programación de tipo Scala para la palabra clave `this`?



types metaprogramming (3)

Estoy tratando de abrirme camino para comprender la programación de tipos en Scala, y he descubierto que la mayor parte de lo que se necesita saber acerca de la programación de tipos tiene una contraparte análoga en la programación de valores, como se refleja en la página de la wiki de programación de nivel . Sin embargo, no he encontrado la analogía para this palabra clave o auto-tipos. Sospecho que tal vez no tenga sentido esperar tal cosa, pero pensé que iba a preguntar.

Por ejemplo, puedo escribir lo siguiente para representar valores booleanos como valores en tiempo de ejecución:

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 }

Aquí mi imp son capaces de aprovechar el hecho de que no importa si soy un objeto falso o un objeto verdadero para ser definido correctamente. FalseVal objetos My TrueVal y FalseVal pueden heredar el mismo código.

Puedo hacer construcciones de programación de nivel de tipo análogas, pero no entiendo cómo definir And e Imp en mi rasgo base.

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 }

Puedo ver dónde quizás no tiene sentido que mis tipos hereden tipos, pero ciertamente heredan tipos abstractos. ¿Hay alguna manera de definir And e Impl en mi BoolType , o tengo que definir cada uno en los respectivos caracteres TrueType y FalseType ?


¿Por qué no usar this palabra clave? Cuando exploré la programación de nivel de tipo, no pude ver una diferencia al usar esto en lugar de uno mismo.

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] }


Siempre puede definir un tipo abstracto en su tipo base booleana de la siguiente manera:

trait MyBool extends BoolType{ type This <: BoolType } trait TrueType extends BoolType{ type This = TrueType }

y debes ser bueno para ir con una referencia a ti mismo. Luego puede usar las leyes de DeMorgan para hacer lo siguiente

!(x && y) == (!x || !y)

Luego, con un doble negativo, puedes ponerte en condiciones:

!(!x || !y) == !!(x && y) == (x && y)


Sugeriría usar self , ejemplo de tu blog ajustado:

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 }