scala - 根据Scala中的一系列表达式构造一个列表

标签 scala dsl

当我尝试在Scala中构建内部DSL时,遇到一个常见问题,而我却无法制定解决方案。为了使事情看起来更像是一种典型的语言,我希望语法看起来像这样:

model 'Foo {
  decl 'Real 'x;
  decl 'Real 'y;
}

实际上,有几个问题。第一个问题是在此处获取model对象,以这种方式接受两个参数。如果有人有任何想法,请告诉我。但是我要做的却是做一些类似的事情:
model('Foo) {
  ...
}

现在,其中的model是一个函数,该函数然后使用apply方法返回对象,该方法然后使用随后的lambda。我可以忍受。我也可能在lambda内部遇到类似的问题,所以里面的像decl 'Real 'xdecl('Real,'x)这样的东西。但是,我想做的是获取波浪形括号内所有这些表达式的结果,以“返回”列表。换句话说,我要写的是这样的东西:
model 'Foo {
  decl('Real,'x);
  decl('Real,'y);
}

其中decl(...)的计算结果为Declaration类型,然后{...}的计算结果为List[Declaration]。我怀疑有某种使用隐式方法做到这一点的方法,但我一直找不到。简而言之,我想做的是:
model 'Foo {
  decl('Real,'x);
  decl('Real,'y);
}

评估为...的等价物
model 'Foo {
  decl('Real,'x) ::
  decl('Real,'y) ::
  Nil
}

意见或建议?

最佳答案

首先,您可以尝试使用变量参数列表,该列表允许您使用逗号而不是分号:

case class Declaration(name: String)

def decl( s: String ) = Declaration(s)

case class Model( sym: Symbol, decls: List[Declaration] )

def model( sym: Symbol)( decls: Declaration* ) =
  Model( sym, decls.toList )

val m = model( 'Foo )(
  decl( "bar" ), 
  decl( "baz" ) 
)

另外,您可以扩展trait来去除一些括号和逗号:
case class ModelBuilder( sym: Symbol ) {
  def using( decls: Declarations ) = Model( sym, decls.toList )
}

trait Declarations {

  protected var decls = List[Declaration]()

  protected def decl( s: String ) = 
decls ::= Declaration( s )

  def toList = decls
}

def model( sym: Symbol ) = ModelBuilder( sym )

model( 'Foo ) using new Declarations {
  decl( "bar" )
  decl( "baz" )
}

关于scala - 根据Scala中的一系列表达式构造一个列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10139015/

相关文章:

scala - “Future.successful(None)”和 “Future(None)”有什么区别

kotlin - 如何基于 TeamCity Kotlin DSL 中的现有构建步骤创建自定义构建步骤?

ruby - 使 Ruby block 返回一个数组?

f# - 使用 SRTP 在 F# 中实现无标记最终编码

dsl - Xtext如何通过实例通过限定名称引用变量?

scala - 使用可变变量编写 while 循环的函数式方法

Scala宏天堂: How do I get an annotation's arguments using macro annotations?

java - 为什么我添加了 "cppInclude"解析器然后整个 g4 不起作用

scala - 如何在 SBT .scala 项目配置中从多个非托管目录添加 jar

list - Scala:替代列表语法(如果可能,使用方括号)