che*_*hen 11 erlang functional-programming
作为函数式语言的新手(几周前我开始接触Erlang - 第一个可以让我开始使用的函数式语言).
我开始写一些小的算法(如left_rotate_list,bubble_sort, merge_sort等).我发现自己常常迷失在诸如"我应该使用帮助列表进行中间结果存储吗?"等决策中.并且"我应该创建一个辅助函数来执行此操作吗?"
过了一会儿,我发现函数式编程(如果我说的话没有意义的话,请跟我一点)鼓励"自上而下"的设计:即,当我做merge_sort时,你首先记下所有的合并排序步骤,并将它们命名为单独的辅助函数; 然后逐个实现这些辅助函数(如果需要进一步划分这些辅助函数,请以相同的方法执行).
这似乎与OO设计略有矛盾,您可以从底层开始构建基本数据结构,然后将数据结构和算法组合成您想要的.
感谢您的评论.是的,我想得到关于如何"用函数式语言思考"的建议(就像"用Java思考","用C++思考").
Chr*_*ian 10
答案是函数式编程是使用函数进行编程,因为它们是在数学中定义的(简而言之,是将值从域映射到codomain的无副作用的东西).实际上将其转化为"如何思考"是一个难以详尽解释的挥手部分,但我将对我的一些想法进行抽样:
第一个与模糊相关:"优雅的代码".列表推导可以呈现非常简洁和数学方程式,如函数定义.只需看看LC实现的快速排序.这就是我如何定义优雅,简洁并使所有行为清晰.不是那种perl code-golf,你最常用的是简洁和神秘.
第二个是我在所有编程中日常使用的东西.将代码划分为当前状态的函数(方法,例程等),这些函数是无副作用的计算,为下一个要采取的操作提供输入(即使是下一个要采取的操作).返回值时,将其提供给执行所描述操作的例程,然后重新开始.
在我的脑海中,我将Erlang过程描绘为一个状态机图,其中每个顶点是一个副作用和一个函数,其输出是从顶点中选择的边.对副作用的高度重视是函数式编程范式教给我的东西.特别是在Erlang中,因为副作用在并发性方面确实很重要,而且Erlang使得并发性非常可用.
同样地,一些孤立的部落对于3以上的数字只有一个单词,或者对于"我的"/"你的"没有单词.感觉流行的语言没有"这将导致副作用"的词,但功能编程有它.它迫使你一直意识到这一点,这是一件好事.
过了一会儿,我发现函数式编程鼓励了"自上而下"的设计.
嗯,这不是关于"自上而下"或"自下而上"的设计.这是关注手头问题的"内容",而不是"如何".当我开始使用函数式编程时,我发现我一直在回想起forC中的嵌套循环等命令式构造.然后我很快发现尝试将我的命令式思维转换为函数式构造非常困难.我会试着给你一个更具体的例子.我将在C和Haskell中实现一个等效的程序,并尝试在两种情况下跟踪我的思维过程.请注意,出于解释的目的,我已经明确地详细说明了.
在C:
#include <stdio.h>
int main(void)
{
int i, inputNumber, primeFlag = 1;
scanf("%d", &inputNumber);
for(i = 2; i <= inputNumber / 2; i ++)
{
if (inputNumber % i == 0)
{
primeFlag = 0;
break;
}
}
if (primeFlag == 0) printf("False\n");
else printf ("True\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
跟踪我的思考过程:
inputNumber.scanf()写的.primeFlag声明并设置等于1.primeNumber2到2之间的每个数字primeNumber/2.for循环开始了.声明了i要检查的循环变量primeNumber.primeNumber每个i.我们发现即使i是分裂的那一刻,也会primeNumber设置primeFlag为0和break.循环体写.for循环中完成严格的检查过程后,检查其值primeFlag并将其报告给用户.printf()写的.在Haskell:
assertPrime :: (Integral a) => a -> Bool
assertPrime x = null divisors
where divisors = takeWhile (<= div x 2) [y | y <- [2..], mod x y == 0]
Run Code Online (Sandbox Code Playgroud)
跟踪我的思考过程:
null divisors.divisors?首先,让我们写下可能的候选人名单.写下德克萨斯范围从2到数/ 2.mod x y == 0我想得到关于如何"用功能语言思考"的建议
好吧,首先,想想"什么",而不是"如何".这需要很多练习才能习惯.另外,如果您以前是像我这样的C/C++程序员,请不要担心内存!现代语言有一个垃圾收集器,它是为你编写的 - 所以甚至不试图修改变量.另一件帮助我的事情是:在你的程序中写下类似英语的定义来抽象出那些繁重的功能.
\n\n\n一段时间后,我发现函数式编程[\xe2\x80\xa6]鼓励“自上而下”的设计。
\n
我不确定这是一个准确的说法。我最近一直在尝试自学函数式编程,我发现某种“自下而上”的编程风格确实对我有帮助。要使用合并排序的示例:
\n\n:)我可能误用了这个术语,但这对我来说感觉就像是自下而上的设计。函数式编程与面向对象编程不同,但在两者之间切换时,您不需要完全放弃现有的设计技术。
\n