是否有任何基本限制阻止Scala实现模式匹配功能? [英] Is there any fundamental limitations that stops Scala from implementing pattern matching over functions?

查看:92
本文介绍了是否有任何基本限制阻止Scala实现模式匹配功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在诸如SML,Erlang和其他语言的语言中,我们可以定义这样的函数:

  fun reverse [] = [] 
|反向x :: xs =反向xs @ [x];

我知道我们可以像这样在Scala中编写模拟(我知道,这里有很多缺陷代码如下):

$ $ p $ code def def [T](lst:List [T]):List [T] = lst match {
case Nil =>无
案例x :: xs => reverse(xs)++ List(x)
}

但是我想知道,如果我们可以在斯卡拉编写以前的代码,也许可以用后者来解决。

在将来实现这样的语法是否有任何基本限制(我的意思是,真正的基础 - 例如类型推断在scala中的工作方式,或者其他解析器)?



UPD

这是它的一个片段:

  type T 
def reverse(Nil:List [T])= Nil
def reverse(x :: xs:List [T]):List [T] = reverse(xs)++ List(x)


解决方案

它真的取决于你的意思。基本

如果你真的问如果有阻止实现此功能的技术展示,那么我会说答案是。你在谈论desugaring,你在这里正确的轨道上。所有需要做的就是基本上将几个分离的案例拼接成一个单一的函数,这可以作为一个预处理步骤来完成(这只需要语法知识,不需要语义知识)。但是为了让这个更有意义,我定义了一些规则:
$ b $ ul
  • 函数签名是必须的(在Haskell中,举例来说,是可选的,但无论您是一次定义一个函数还是几个部分,它总是可选的)。我们可以尝试安排没有签名的生活,并尝试从不同的部分中提取它,但缺乏类型信息会很快到达字节。一个更简单的说法是,如果我们试图推断一个隐式签名,那么我们也可以为所有的方法去做。但事实是,在scala中有明确的标记有很好的理由,我无法想象要改变它。

  • 所有部分必须在相同范围内定义。首先,它们必须在相同的文件中声明,因为每个源文件都是单独编译的,因此一个简单的预处理器不足以实现该功能。其次,我们最后还是得到一个方法,所以将所有部分放在同一个范围内是很自然的。

  • 对于这样的方法,重载是不可能的(否则我们会需要重复每个部分的签名,以便预处理器知道哪个部分属于哪个重载)
  • 将零件添加(缝合)到生成的 match 按照它们声明的顺序



  • 所以下面是它的样子:

      def reverse [T](lst:List [T]):List [T] //完全像一个抽象def(提供签名)
    // ....一些不相关的代码在这里...
    def reverse(Nil)=无
    // ....另一个不相关的代码在这里...
    def reverse(x :: xs)= reverse(xs)++ List(x)



    <

      def reverse [T](list:List [T]):List [T ] = lst match {
    case Nil =>无
    案例x :: xs => reverse(xs)++ List(x)
    }
    // ....一些不相关的代码在这里...
    // ....另一些不相关的代码在这里.. 。

    很容易看出上述转换非常机械,只需操作一个源代码AST(接受这个新构造的轻微修改的语法产生的AST),并将其转换为目标AST(由标准Scala语法产生的AST)。
    然后我们可以像往常一样编译结果。

    所以你去了,用一些简单的规则,我们可以实现一个预处理器来完成所有的工作以实现这一新功能。
    $ b b
    $ b 如果按照基本要求有什么会使这个功能不合适的地方,那么可以认为这并不是 。但更重要的是,它并没有带来太多的好处。 Scala的作者实际上倾向于使语言变得更简单(就像内置的功能较少,尝试将某些内置功能移入库中一样),并增加一种新语法,这种语法的可读性并不高,这与简化的目标背道而驰。

    In languages like SML, Erlang and in buch of others we may define functions like this:

    fun reverse [] = []
    |   reverse x :: xs  = reverse xs @ [x];
    

    I know we can write analog in Scala like this (and I know, there are many flaws in the code below):

    def reverse[T](lst: List[T]): List[T] = lst match {
      case Nil     => Nil
      case x :: xs => reverse(xs) ++ List(x)
    }
    

    But I wonder, if we could write former code in Scala, perhaps with desugaring to the latter.

    Is there any fundamental limitations for such syntax being implemented in the future (I mean, really fundamental -- e.g. the way type inference works in scala, or something else, except parser obviously)?

    UPD
    Here is a snippet of how it could look like:

    type T
    def reverse(Nil: List[T]) = Nil
    def reverse(x :: xs: List[T]): List[T] = reverse(xs) ++ List(x)
    

    解决方案

    It really depends on what you mean by fundamental.

    If you are really asking "if there is a technical showstopper that would prevent to implement this feature", then I would say the answer is no. You are talking about desugaring, and you are on the right track here. All there is to do is to basically stitch several separates cases into one single function, and this can be done as a mere preprocessing step (this only requires syntactic knowledge, no need for semantic knowledge). But for this to even make sense, I would define a few rules:

    • The function signature is mandatory (in Haskell by example, this would be optional, but it is always optional whether you are defining the function at once or in several parts). We could try to arrange to live without the signature and attempt to extract it from the different parts, but lack of type information would quickly come to byte us. A simpler argument is that if we are to try to infer an implicit signature, we might as well do it for all the methods. But the truth is that there are very good reasons to have explicit singatures in scala and I can't imagine to change that.
    • All the parts must be defined within the same scope. To start with, they must be declared in the same file because each source file is compiled separately, and thus a simple preprocessor would not be enough to implement the feature. Second, we still end up with a single method in the end, so it's only natural to have all the parts in the same scope.
    • Overloading is not possible for such methods (otherwise we would need to repeat the signature for each part just so the preprocessor knows which part belongs to which overload)
    • Parts are added (stitched) to the generated match in the order they are declared

    So here is how it could look like:

    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)
    

    Which could be trivially transformed into:

    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...
    

    It is easy to see that the above transformation is very mechanical and can be done by just manipulating a source AST (the AST produced by the slightly modified grammar that accepts this new constructs), and transforming it into the target AST (the AST produced by the standard scala grammar). Then we can compile the result as usual.

    So there you go, with a few simple rules we are able to implement a preprocessor that does all the work to implement this new feature.


    If by fundamental you are asking "is there anything that would make this feature out of place" then it can be argued that this does not feel very scala. But more to the point, it does not bring that much to the table. Scala author(s) actually tend toward making the language simpler (as in less built-in features, trying to move some built-in features into libraries) and adding a new syntax that is not really more readable goes against the goal of simplification.

    这篇关于是否有任何基本限制阻止Scala实现模式匹配功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆