Functional programming D语言中的模式匹配

Functional programming D语言中的模式匹配,functional-programming,pattern-matching,d,Functional Programming,Pattern Matching,D,我最近偶然发现了D编程语言,我真的很喜欢它。您可以像在C中一样,在拥有完全硬件访问权限的情况下进行真正高级的编程 我来自一个相当实用的背景(Haskell,scala),我正在寻找一种在D中进行模式匹配的方法,但在D中我什么也没找到。 在Haskell中,模式匹配由语言本身支持。 在Scala中,它是通过case类或提取器(使用unapply方法的普通对象)实现的 在D中可以这样做吗 std.concurrency中的receive方法用于以参与者风格(如erlang和scala)进行并发,它在

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

我来自一个相当实用的背景(Haskell,scala),我正在寻找一种在D中进行模式匹配的方法,但在D中我什么也没找到。 在Haskell中,模式匹配由语言本身支持。 在Scala中,它是通过case类或提取器(使用unapply方法的普通对象)实现的

在D中可以这样做吗

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

语言中没有内置Haskell的模式匹配,但D具有非常通用的编译时和反射功能,允许您匹配库中的类型及其结构。要匹配运行时值,您只能使用普通的
if
/
开关
。。。构造;还可能有助于实现一些运行时匹配技术

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

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

编译时反射的一些说明:


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

正如您已经了解到的,重载和调用(模板化)函数或委托是一种受限制的模式匹配形式。只能在参数类型上进行匹配

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

例如:

如果你感兴趣,你可能想看看

“is”-表达式是在类型上进行模式匹配的另一种方法,请参见


(搜索“iExpression”)。

如果您不坚持使用D2和/或火卫一,您可以使用。它有一个你可以使用的工具。[Edit]D2/Phobos中还有一个regex模块[/Edit]如果你坚持使用D2和/或Phobos,你可以尝试移植它。这不应该太难

Tango是另一种std库。许多tango开发人员和用户不喜欢D2的发展方式,大多数人坚持使用D1。这就是为什么只有一些不完整的D2可用


还有一个项目提供静态编译的正则表达式。我自己已经用过了,而且很有效。但我认为它也只是D1。不过,它同时适用于火卫一和探戈。

该软件包提供了它们的总和类型和模式匹配。

嗯。。。你说的模式匹配到底是什么意思?Mehrdad,我认为Haskell中的模式匹配有点像C++中的模板特化。我不确定我是否理解为什么它被称为模式匹配。说它像Scheme(因为lambda和宏几乎都是模式匹配器)对吗?如果是,那么我想我知道我们要去哪里了。@Mehrdad它被称为模式匹配,因为它是模式匹配,而不是模板专门化。如果你想知道它到底是什么,用谷歌搜索它。2.0版火卫一中有一个正则表达式模块:检查问题是关于什么的,而不是关于正则表达式的
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                                                                                 
}