【问题标题】:pattern matching in DD中的模式匹配
【发布时间】:2011-09-13 00:56:46
【问题描述】:

我最近偶然发现了 D 编程语言,我真的很喜欢它。您可以像在 C 中一样拥有完整的硬件访问权限,同时进行真正高级别的编程。

来自相当实用的背景 (Haskell,scala) 我正在寻找一种在 D 中进行模式匹配的方法,但我在 http://www.digitalmars.com/d/ 上一无所获。 在 Haskell 中,语言本身支持模式匹配。 在 Scala 中,它通过案例类或提取器(具有 unapply 方法的普通对象)来实现。

在 D 中可以做到这一点吗?

std.concurrency 中的 receive 方法用于在 erlang 和 scala 中以 actor 风格进行并发,在这些方法上采用了一堆函数和模式数学。 但我认为它不像其他语言那样灵活。你可以使用警卫吗?你能像在 scala 中那样提取对象的内容吗?

【问题讨论】:

  • 嗯...模式匹配到底是什么意思?你说的是逻辑编程吗?
  • @Mehrdad 我认为 Haskell 中的模式匹配有点像 C++ 中的模板特化。
  • @Red:嗯……我不确定我是否理解为什么它被称为模式匹配。说它像 Scheme 是否正确(因为 lambda 和宏几乎是模式匹配器)?如果是,那我想我知道我们要去哪里了。
  • @Mehrdad 之所以称为模式匹配,是因为它是模式匹配,不是模板特化。如果你想确切地知道它是什么,谷歌它。

标签: functional-programming pattern-matching d


【解决方案1】:

没有像 Haskell 中已知的模式匹配被内置到语言中,但是 D 具有非常通用的编译时间和反射功能,允许您匹配库中的类型及其结构。为了匹配运行时值,您只能使用普通的 if / switch ... 构造; lazy evaluation of function arguments 也可能有助于实现一些运行时匹配技术。

Template Constraints 将允许您根据编译时评估的任何表达式创建函数(模板)重载(D 允许您在编译期间执行几乎所有正常代码)。您也可以使用static if 获得类似的效果。这实际上将允许您匹配类型结构。这也是D中常用的技巧。

您可能会发现 std.algorithm 的代码很有趣,寻找 isInputRange 和类似函数 - 它们对类型结构执行匹配 - 它们将参数的类型限制为特定的typeclass

编译时反射的一些方向:

【讨论】:

    【解决方案2】:

    没有像 Haskell 或 Scala 那样强大的专用模式匹配功能。

    正如您已经发现的那样,重载和调用(模板化)函数或委托是模式匹配的一种受限形式。您只能匹配参数类型。

    您可以在编译时间模板参数上进行模式匹配。也不可能在那里提取对象的内容。但是您可以提取类型的内容。

    例如:

    import std.stdio, std.conv;
    template match(T...){
        enum match = "default case";
    }
    template match(string a : "x", int b : 1, int  c){
        enum match = "matched 1, b="~to!string(b);
    }
    template match(int a, string b, int c : 100){
        enum match = "matched 2, b="~b;
    }
    template match(T : T[]*[]){
        enum match = "matched 3, an array of pointers to an array of "~T.stringof;
    }
    
    
    void main(){
        int a=100;
        writeln(match!("x",1,5));        // "matched 1, b=1"                                                                                                     
        writeln(match!(12,"str"));       // "default case"                                                                                                       
        writeln(match!(12,"str",100));   // "matched 2, b=str"                                                                                                   
        writeln(match!(int*[]*[]));      // "matched 3, an array of pointers to an array of int*"                                                                
        //writeln(match!(12,"str",a));   // would be error, because 'a'                                                                                            
                                         // is not evaluable during compile time                                                                                 
    }
    

    如果你有兴趣,不妨看看http://d-programming-language.org/template.html

    'is' - 表达式是对类型进行模式匹配的另一种方式,请参阅

    http://d-programming-language.org/expression.html(搜索“IsExpression”)。

    【讨论】:

      【解决方案3】:

      sumtype 包提供求和类型和模式匹配。

      【讨论】:

        【解决方案4】:

        如果您不坚持使用 D2 和/或 Phobos,您可以使用 tango library。它有一个您可以使用的regex module。 [Edit] D2/Phobos 中还有一个正则表达式模块 [/Edit] 如果你坚持使用 D2 和/或 Phobos,你可以尝试移植它。应该不会太难。

        Tango 是一个替代标准库。许多探戈开发者和用户不喜欢 D2 的发展方式,大多数人都坚持 D1。这就是为什么只有一些不完整的port 到 D2 可用。

        还有一个项目scregex,它提供了静态编译的正则表达式。我自己已经使用了它并且它有效。但我认为它也仅限于 D1。然而,它适用于火卫一和探戈。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-26
        • 2022-01-11
        • 1970-01-01
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        相关资源
        最近更新 更多