Haskell中的模式匹配是什么?它与保护方程有什么关系?
我试过寻找一个简单的解释,但我还没找到.
编辑:有人标记为家庭作业.我不再去上学了,我只是在学习Haskell,而我正在努力理解这个概念.纯粹出于兴趣.
我刚刚发现了函数编程风格,我相信它会减少开发工作,使代码更容易阅读,使软件更易于维护.然而,问题是我在说服任何人.
好吧,最近我有机会就如何减少软件开发和维护工作发表演讲,我想向他们介绍函数式编程的概念以及它如何使团队受益.我有这样的想法,即向人们展示两组完全相同的代码,一个以非常强制的方式编码,另一个以非常实用的方式编写,以表明函数式编程可以使代码更简单,更容易理解和因此可维护.是否有这样的例子,除了Luca Bolognese的着名的平方和例子?
Haskell 和 Rust(以及我不知道的其他语言)有一个他们称之为“模式匹配”的发展。下面是 Haskell 中的一个例子:
data Event = HoldKey Char | PressKey Char | Err String
someFunc = let
someEvent <- doSomeStuff
-- What follows is a case expression using pattern matching
thingINeed <- case someEvent of
HoldKey keySym -> process keySym
PressKey keySym -> process keySym
Err err -> exit err
in keepDoingStuff
Run Code Online (Sandbox Code Playgroud)
在 Raku 中与此最接近的似乎是 多方法 multifunctions(术语在下面的答案中固定,但 multimethods 也可以工作)。
class Hold { has $.key; }
class Press { has $.key; }
class Err { has $.msg; }
multi …Run Code Online (Sandbox Code Playgroud) 哪些不仅仅是功能性的语言具有代数数据类型(或类似的东西)和模式匹配?我也对多范式语言感兴趣 - 我知道Ocaml和F#是添加了OO的ML方言,因此它们继承了ML的代数数据类型.
它们可以使用enums和unions 进行模拟(如C,C++,...更多?),但这很快变得麻烦和丑陋,如果你在模式匹配中忘记了一个案例,编译器就无法发出警告或者(更可行,更危险)当以"错误的方式"访问联合时,即,Left当它实际上是一个值时,你要求一个值的字段Right(你得到的是对碰巧发生的那些位的无意义的重新解释)在那里).
我听说Pascal有类似标记的联合,而Cyclone语言也支持标记的联合.维基百科还提到了阿达和阿尔戈尔.还有其他语言吗?
(如果您从未听说过代数数据类型,您可以阅读函数式语言中"什么是'模式匹配'的答案?"以获得精彩的介绍.
language-agnostic programming-languages functional-programming algebraic-data-types
我正在寻找一种检测冗余规则的算法.
规则具有固定数量的输入参数,并且每个参数具有不同的域.
考虑三个规则参数颜色,材质和尺寸:
每个规则可以匹配参数的多个值或匹配任何值.选择匹配所有参数值的第一个规则.没有否定规则,但域是固定的,因此可以通过添加所有其他域来实现否定.
+--------------------------------------------------++-----------------
| Rule Parameters || Rule Action
+----------------+------------------+--------------++-----------------
| Color | Material | Size || ==> Price
+----------------+------------------+--------------++-----------------
Rule 1 | Red | Wood, Glass | Large || $100
Rule 2 | Red | Aluminium | Large || $200
Rule 3 | Blue or Green | Wood | Medium || $300
Rule 4 | Red | ** Any ** | Large || $400 <== …Run Code Online (Sandbox Code Playgroud) 在某些语言中,如果函数返回一个数组,那么与将数组存储在变量中相反,然后检索单个元素,如下所示:
var someValues = getSomeValues();
var firstElement = someValues[0];
Run Code Online (Sandbox Code Playgroud)
您可以在函数调用之后直接使用数组索引表示法来检索返回数组的元素,如下所示:
var firstElement = getSomeValues()[0];
Run Code Online (Sandbox Code Playgroud)
这种结构或语法是什么?它有一个特殊的名字吗?
我一直在考虑做自己的语言(实用性:这是一个思想实验).我提出的一个想法是语内语义变异.你基本上编写了语义正则表达式,用等效代码替换.您可以在D-中稍微不那么直接地看到它 - 它们具有转换为D代码的字符串混合.除了我打算隐含地,并以更循环的方式.
现在,我来自C++.所以,如果你考虑:
string a, b, c, d;
// do stuff
a = b + c + d;
Run Code Online (Sandbox Code Playgroud)
此代码会产生各种临时性.即使你有左值参考,你也会创建临时值,它们只会被更有效地重复使用.但它们仍然存在并仍然浪费性能.在最简单的情况下,我在考虑如何消除这些问题.您可以编写一个语义正则表达式,将其转换为最优化的形式.
string a, b, c, d;
// do stuff
a.resize(b.size() + c.size() + d.size());
a = b; a += c; a += d;
Run Code Online (Sandbox Code Playgroud)
如果我实现了std :: string,我可能会写得更快.关键是它们是隐式的 - 当你使用std :: string类时,std :: string实现者编写的公理会影响任何std :: string代码.您可以将其放入现有的C++代码库中,重新编译,并获得std :: string实现者可以免费设想的最快的字符串连接.
目前,您可以进行的优化是有限的,因为您只有语言允许的上下文,在这种情况下,C++中的运算符重载只接受两个参数,this和arg.但语义注册表几乎可以占用您可能需要的所有上下文 - 因为您可以指定匹配的内容 - 甚至可以匹配宿主语言中不存在的语言功能.例如,交换是微不足道的
string a;
a.size;
Run Code Online (Sandbox Code Playgroud)
对于
string a;
a.size();
Run Code Online (Sandbox Code Playgroud)
如果你想窃取C#属性.您可以匹配类定义并实现编译或运行时反射等.
But, I mean, it could get confusing. If there was a bug, …
我喜欢阅读有关编程理论的内容,所以你能告诉我是否有任何面向对象的静态类型语言允许变量有几种类型?pesudocode中的示例:
var value: BigInteger | Double | Nil
Run Code Online (Sandbox Code Playgroud)
我想到了在这个对象上调用方法的方法.如果对象值的类型为BigInteger | 双语言可以让用户只能拨打共享方法(湖加,减),但是当该类型的BigInteger | 双| Nil然后Nil的对象没有方法加减,所以我们不能对这个对象做任何有用的事情,因为它只有很少的共享方法(比如toString).
那么有什么想法应该如何在静态类型面向对象语言中使用少量类型调用变量上的方法?
theory programming-languages language-theory language-design
我有一个这样的方法:
def close(): Unit = {
things.foreach {
case (attr1, attr2) =>
File.<do_something>(attr1, attr2)
}
}
Run Code Online (Sandbox Code Playgroud)
这是一种什么样的结构?我知道它正在遍历所有things地图 if <attr1, attr2>。我可以访问事物本身吗?如果我还想对thing. 我怎样才能做到这一点?