om-*_*nom 20 syntax functional-programming scala pattern-matching
在像SML,Erlang这样的语言中,我们可以定义这样的函数:
fun reverse [] = []
| reverse x :: xs = reverse xs @ [x];
Run Code Online (Sandbox Code Playgroud)
我知道我们可以像这样在Scala中编写模拟(我知道,下面的代码中有很多缺陷):
def reverse[T](lst: List[T]): List[T] = lst match {
case Nil => Nil
case x :: xs => reverse(xs) ++ List(x)
}
Run Code Online (Sandbox Code Playgroud)
但我想知道,如果我们可以在Scala中编写前代码,也许可以放弃后者.
这种语法在未来是否有任何基本限制(我的意思是,真的很基础 - 例如类型推断在scala中的工作方式,或者除了解析器之外的其他东西)?
UPD
以下是它的外观片段:
type T
def reverse(Nil: List[T]) = Nil
def reverse(x :: xs: List[T]): List[T] = reverse(xs) ++ List(x)
Run Code Online (Sandbox Code Playgroud)
Rég*_*les 14
这实际上取决于你的基本意味着什么.
如果你真的在问" 如果有技术的showstopper会阻止实现这个功能 ",那么我会说答案是否定的.你说的是脱贫,你在这里走在正确的轨道上.所有要做的就是将几个分离案例基本上拼接成一个单独的函数,这可以仅仅作为预处理步骤来完成(这只需要语法知识,不需要语义知识).但为了这个甚至有意义,我会定义一些规则:
match的部分所以这是它的样子:
def reverse[T](lst: List[T]): List[T] // Exactly like an abstract def (provides the signature)
// .... some unrelated code here...
def reverse(Nil) = Nil
// .... another bit of unrelated code here...
def reverse(x :: xs ) = reverse(xs) ++ List(x)
Run Code Online (Sandbox Code Playgroud)
这可以简单地转化为:
def reverse[T](list: List[T]): List[T] = lst match {
case Nil => Nil
case x :: xs => reverse(xs) ++ List(x)
}
// .... some unrelated code here...
// .... another bit of unrelated code here...
Run Code Online (Sandbox Code Playgroud)
很容易看出上述转换是非常机械的,可以通过操纵源AST(由接受这种新构造的略微修改的语法产生的AST),并将其转换为目标AST(由AST生成的AST)来完成.标准的斯卡拉语法).然后我们可以像往常一样编译结果.
所以你可以通过一些简单的规则来实现一个预处理器,它可以完成所有工作来实现这个新功能.
如果从根本上说你会问" 有什么东西可以使这个功能不合适 "那么可以说这不会让人感到非常不稳定.但更重要的是,它并没有带来太大的影响.Scala的作者实际上倾向于使语言更简单(如在较少的内置功能中,试图将一些内置功能移动到库中)并添加一种不太可读的新语法违背了简化的目标.
在SML中,您的代码片段实际上只是语法糖(语言规范术语中的"派生形式")
val rec reverse = fn x =>
case x of [] => []
| x::xs = reverse xs @ [x]
Run Code Online (Sandbox Code Playgroud)
这与你展示的Scala代码非常接近.因此,没有没有"基本"原因,Scala无法提供相同类型的语法.主要问题是Scala需要更多的类型注释,这使得这种速记语法在一般情况下的吸引力大大降低,而且可能不值得.
另请注意,您建议的特定语法不能顺利运行,因为无法在语法上区分一个逐个函数的函数和两个重载函数.您可能需要一些替代语法,类似于使用" |"的SML .