在函数式编程中究竟是什么'如何做和做什么'或'关注结果,而不是步骤'

时间:2013-02-25 01:25:12

标签: functional-programming imperative-programming

我很难理解函数式编程中的“不要考虑如何做而是做什么”(关注结果,而不是步骤)的概念。假设我们有一种语言将函数视为一等公民而没有用于迭代的内置函数(例如Scala中的forAll)。在那种情况下,我们首先要创建一个函数,告诉我们如何迭代给定的数据结构呢?因此,如果它自己的语言没有提供足够的功能,那么除了具有作为一等公民的功能之外,它将与命令式的编码几乎相同不是吗?

如果我错了,请纠正我。以下是我提到的资源。

Video lecture

Some articles

1 个答案:

答案 0 :(得分:2)

“如何”和“什么”是同一枚硬币的两面,有时以某种方式思考是有用的。考虑“做什么”是一种思考递归的好方法,特别是对于没有太多编写递归函数经验的人。 “如何”意味着一系列步骤,而“什么”意味着一系列定义。让我们考虑你的迭代示例(我将使用Haskell,因为我不知道Scala,但概念应该是可以直接翻译的。)

Haskell的迭代函数称为map,但假设我们想自己编写它。如果我们没有太多的递归经验,可能很难想象如何编写一个函数(map)将另一个函数(f)应用于列表的每个元素(“映射”) f超过list)。这是我们想要的函数的类型签名:

map :: (a -> b) -> [a] -> [b]

让我们试着考虑一个应用于列表中每个元素的函数的“内容”。它是应用于第一个元素的函数,后面是映射到列表其余部分的函数。那么让我们编写代码:

map f (firstElement:restOfList) = (f firstElement):(map f restOfList)

现在我们差不多完成了。唯一剩下的就是处理基本情况。如果列表为空怎么办?很明显,映射到空列表的任何函数都是空列表,因此我们将编码:

map _ [] = []

我们已经完成了!现在,如果您可以考虑“如何”并编写上述代码,请继续(因为我获得了更多经验,我倾向于更频繁地这样做)。然而,如果你发现自己陷入困境,那就用“什么”来思考是一种有用的技术。