Scala中的内部DSL元组转换为类

时间:2013-01-25 21:49:22

标签: scala dsl

我正在尝试在Scala中构建内部DSL。我有以下类型:

case class A(name:String)
case class Group(list:A*) // it can also be list:List[A]

使用常规语法创建一组A,如下所示:

val group1 = Group(A("a1"), A("a2"), ...)

非常难看。如果可能的话,我想将小组视为(A("a1"), A("a2"), ...),可能稍后("a1", "a2", ...)

我无法弄清楚如何将(A("a1"), A("a2"), ...)转换为Group(A("a1"), A("a2"), ...)。如果我们可以将(A("a1"), A("a2"), ...)转换为类Group的实例,那就太好了。 (我不在乎我是否不能在内部指定无限数量的A。最多8个A就足够了)

所以我的问题是:有没有办法将元组转换为类的特定实例?如果没有,你会如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

首先,在Scala中解决任何arity 元组的问题是令人讨厌的,因为元组类是不同的,所以你必须有8或22或任何你希望支持转换的arity

但无论如何,元组是针对异构类型的东西,而你在这里需要一个常见类型的集合。因此,虽然元组语法可能看起来不错,但我建议不要在DSL中尝试使用它。坚持收藏或只是别名Group类型,即使以额外字符的价格,例如。

object A {
  implicit def fromString(name: String) = A(name)
}
case class A(name: String)
case class Group(elem: A*)

val G = Group
G("a1", "a2")

如果你真的想支持元组,那么下面的内容就是:

object Group {
  implicit def fromTuple2[A1 <% A, A2 <% A](t: (A1, A2)) = Group(t._1, t._2)
}
case class Group(elem: A*)

("a1", "a2"): Group