什麼是函式式程式設計思維?

2021-08-28 16:39:41 字數 1728 閱讀 2133

我為什麼要把我的知乎回答搬到這裡呢……大概是太久沒發東西了來湊數吧。

函式式程式設計與命令式程式設計最大的不同其實在於:

函式式程式設計關心資料的對映,命令式程式設計關心解決問題的步驟

這裡的對映就是數學上「函式」的概念——一種東西和另一種東西之間的對應關係。

這也是為什麼「函式式程式設計」叫做「函式式程式設計」。

這是什麼意思呢?

假如,現在你來到 google 面試,面試官讓你把二叉樹映象反轉一下(大霧

幾乎不假思索的,就可以寫出這樣的 python **:

def inverttree(root):

if root is none:

return none

root.left, root.right = inverttree(root.right), inverttree(root.left)

return root

好了,現在停下來看看這段**究竟代表著什麼——

它的含義是:首先判斷節點是否為空;然後翻轉左樹;然後翻轉右樹;最後左右互換。

這就是命令式程式設計——你要做什麼事情,你得把達到目的的步驟詳細的描述出來,然後交給機器去執行。

這也正是命令式程式設計的理論模型——圖靈機的特點。一條寫滿資料的紙帶,一條根據紙帶內容運動的機器,機器每動一步都需要紙帶上寫著如何達到。

那麼,不用這種方式,如何翻轉二叉樹呢?

函式式思維提供了另一種思維的途徑——

所謂「翻轉二叉樹」,可以看做是要得到一顆和原來二叉樹對稱的新二叉樹。

這顆新二叉樹的特點是每乙個節點都遞迴地和原樹相反。

用 haskell **表達出來就是:

data tree a = nil | node a (tree a) (tree a)

deriving (show, eq)

invert :: tree a -> tree a

invert nil = nil

invert (node v l r) = node v (invert r) (invert l)

(防止看不懂,翻譯成等價的 python )

def invert(node):

if node is none:

return none

else

return tree(node.value, invert(node.right), invert(node.left))

這段**體現的思維,就是舊樹到新樹的對映——對一顆二叉樹而言,它的映象樹就是左右節點遞迴映象的樹。

這段**最終達到的目的同樣是翻轉二叉樹,但是它得到結果的方式和 python **有著本質的差別:通過描述乙個 舊樹->新樹 的對映,而不是描述「從舊樹得到新樹應該怎樣做」來達到目的。

那麼這樣思考有什麼好處呢?

首先,最直觀的角度來說,函式式風格的**可以寫得很精簡,大大減少了鍵盤的損耗(

更重要的是,函式式的**是「對對映的描述」,它不僅可以描述二叉樹這樣的資料結構之間的對應關係,任何能在計算機中體現的東西之間的對應關係都可以描述——比如函式和函式之間的對映(比如 functor);比如外部操作到 gui 之間的對映(就是現在前端熱炒的所謂 frp)。它的抽象程度可以很高,這就意味著函式式的**可以更方便的復用。

同時,將**寫成這種樣子可以方便用數學的方法進行研究(這就是為什麼可以扯上「___範疇上的___」這種數學上的高深概念)

至於什麼科里化、什麼資料不可變,都只是外延體現而已。

什麼是函式式程式設計

1 函式式程式設計 它屬於 結構化程式設計 的一種,主要思想是把運算過程盡量寫成一系列巢狀的函式呼叫。函式程式語言最重要的基礎是 演算 lambda calculus 而且 演算的函式可以接受函式當作輸入 引數 和輸出 返回值 補充 lambda演算是通過乙個函式來解決這個問題,而這個函式又是由一系...

什麼是函式式程式設計

通過把大段 拆成函式,通過一層一層的函式呼叫,就可以把複雜任務分解成簡單的任務,這種分解可以稱之為面向過程的程式設計。函式就是面向過程的程式設計的基本單元。而函式式程式設計 注意多了乙個 式 字 functional programming,雖然也可以歸結到面向過程的程式設計,但其思想更接近數學計算...

什麼是函式式程式設計

定義函式式程式設計其實就是編寫非故意 的程式。課外知識 什麼是函式函式簡單的說就是從a 定義域 到b 值域 的乙個對映過程。當然具體的函式還有各種限制,具體見鏈結。所以函式式程式設計也應該是乙個從入參到返回值的黑盒子。概述並不是所有人在函式式程式設計的定義上達成了共識。一般來說,函式式程式設計是使用...