在Scala DSL中创建对换行符没有有趣限制的控件构造

在Scala DSL中创建对换行符没有有趣限制的控件构造,scala,Scala,我正在为契约式设计编写一个简单的DSL。以下是我希望能够写的: def incrX( i : Int ) { val x0 = x pre( i >= 0 ) post( x == x0+i ) in { x += i } } 到目前为止,我所做的是使pre成为一个trait方法,它接受一个布尔值并返回一个对象。该对象有一个方法post,该方法接受布尔值并返回另一个对象。该对象在中有一个方法,该方法获取一

我正在为契约式设计编写一个简单的DSL。以下是我希望能够写的:

def incrX( i : Int ) {
      val x0 = x 
      pre( i >= 0 )
      post( x == x0+i )
      in {
          x += i 
      } }
到目前为止,我所做的是使
pre
成为一个trait方法,它接受一个布尔值并返回一个对象。该对象有一个方法
post
,该方法接受布尔值并返回另一个对象。该对象在中有一个方法
,该方法获取一个单位并返回()。有了这个计划,我就可以写作了

def incrX( i : Int ) {
      val x0 = x 
      pre( i >= 0 ) post( x == x0+i ) in { x += i } }

甚至

def incrX( i : Int ) {
      val x0 = x 
      (pre( i >= 0 )
       post( x == x0+i )
       in {
          x += i 
      } ) }
很好,但不是我想要的


有什么方法可以实现我想要的吗?

就好看的代码而言,我喜欢“点对齐”的概念,它在Scala中非常常见,可以解决语法问题

因此,假设如下所示:

object Contract {
  def pre(c: => Boolean) = new ContractWithPre(c)
}
class ContractWithPre(preCond: => Boolean) {
  def post(c: => Boolean) = new ContractWithPreAndPost(preCond, c)
}
class ContractWithPreAndPost(preCond: => Boolean, postCond: => Boolean) {
  def in(body: => Unit) {
    require(preCond)
    body
    ensuring(postCond)
  }
}
你可以写:

Contract
  .pre(i >= 0)
  .post(x == x0+i)
  .in {
    x += i 
  } 

例如,在
pre
post
部分之间使用
&
是可以接受的吗?Scala有一个内置的API,您可以使用它,比如:
def incrX(i:Int)={val x0=x;require(i>=0);(x+=i)确保(x==x0+i);}
@GáborBakos i可能,“如果没有其他选择的话,”wingedsubmariner说,那是真的。我喜欢这个答案,但它不能肯定地回答我的“这能做到吗”的问题。相反,它很好地回答了一个显而易见的后续问题:“如果它不能像我所希望的那样完成,还有什么其他方法可以创建类似的语法。”@Theodore Norvell:如果你问“这可以在不修改代码的情况下完成吗”(比如:通过一些外部修改来改变解析器的行为),那么我的答案是:不,我目前没有看到任何可能性,除了修改解析器。也就是说,我仍然认为你想要的是可能的,仅仅通过一个非常小的语法修改:)。
Contract
  .pre(i >= 0)
  .post(x == x0+i)
  .in {
    x += i 
  }