Functional programming “学习建议”;如何思考“功能性”;?
作为函数式语言的新手(我几周前开始接触Erlang,这是我能接触到的第一种函数式语言) 我开始编写一些小算法(如Functional programming “学习建议”;如何思考“功能性”;?,functional-programming,erlang,Functional Programming,Erlang,作为函数式语言的新手(我几周前开始接触Erlang,这是我能接触到的第一种函数式语言) 我开始编写一些小算法(如左旋转列表,气泡排序,合并排序等)。我发现自己经常迷失在决策中,比如“我应该使用助手列表来存储中间结果吗?”和“我应该创建一个助手函数来实现这一点吗?” 过了一段时间,我发现函数式编程(如果我说的毫无意义,请容忍)鼓励“自上而下”的设计:即,当我进行merge_sort时,您首先写下所有合并排序步骤,并将它们命名为单独的helper函数;然后一个接一个地实现这些辅助函数(如果需要进一步
左旋转列表
,气泡排序,
合并排序
等)。我发现自己经常迷失在决策中,比如“我应该使用助手列表来存储中间结果吗?”和“我应该创建一个助手函数来实现这一点吗?”
过了一段时间,我发现函数式编程(如果我说的毫无意义,请容忍)鼓励“自上而下”的设计:即,当我进行merge_sort时,您首先写下所有合并排序步骤,并将它们命名为单独的helper函数;然后一个接一个地实现这些辅助函数(如果需要进一步划分这些辅助函数,请使用相同的方法)
这似乎与OO设计有点矛盾,在OO设计中,您可以从底层开始构建基本的数据结构,然后将数据结构和算法组装成您想要的
谢谢你的评论。是的,我想获得关于如何“用函数式语言思考”(就像“用Java思考”、“用C++思考”)的建议
过了一会儿,我发现函数式编程[…]鼓励“自上而下”的设计
我不确定这是不是一个准确的说法。我最近一直在自学函数式编程,我发现一种“自下而上”的编程风格确实对我有帮助。要使用合并排序示例,请执行以下操作:
- 首先看看基本情况。如何对0/1元素数组进行排序
- 接下来,看看base+1,base+2,…案例。最终,您应该看到一种模式(分解为子问题、求解子问题、组合子解决方案),它允许您编写一个通用的递归案例,而不是最终到达基本案例
- 分解成子问题很容易,但组合子解决方案要困难一些。您需要一种将两个排序数组合并为一个排序数组的方法
- 现在把所有的东西放在一起。祝贺您,您刚刚编写了合并排序<代码>:)
我可能误用了这个词,但这对我来说就像是自下而上的设计。函数式编程不同于面向对象编程,但在两者之间切换时,您不需要完全放弃现有的设计技术。答案是函数式编程是使用函数编程,正如它们在数学中定义的那样(简而言之,无副作用的东西将价值从域映射到编码域)。要真正将其转化为“如何思考”是一个很难详尽描述的挥手部分,但我将列举我的一些想法:
for
循环。然后我很快发现,尝试将我的命令式思维转换为函数式结构非常困难。我将试着给你一个更具体的例子。我将在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;
}
assertPrime :: (Integral a) => a -> Bool
assertPrime x = null divisors
where divisors = takeWhile (<= div x 2) [y | y <- [2..], mod x y == 0]