簡體   English   中英

函數式編程公理

[英]Functional programming axioms

我正在學習Clojure的函數式編程,並希望加深對函數范式的理論理解(不僅僅是Clojure的語法)。

我正在尋找公理公式 ,每個函數技術如遞歸,映射,減少,缺點,第一和休息是如何相互關聯的,它們是可衍生的/可組合的,並且它是一切背后的終極公理。

例如,我意識到map只能使用recurfirstrestcons函數來實現,當然映射函數本身recur傳遞給map

之后,我也意識到map也可以使用reduce實現,並且可以使用recurfirstrest再次實現reduce 也可以使用reduce實現filter

我覺得我開始圍繞函數式編程,但仍然很難看出哪些是最終的構建塊,即構成任意函數的最小抽象關鍵字集合。 使用map示例,第二種方法使用少一個抽象來定位同一目標。 那么,功能范式的一些終極公理能夠幫我看清大局嗎?

從lambda(在clojure中稱為fn ),你可以得到任何其他東西。 例如,讓我們做一下導出cons的經典練習, first ,用fn rest

(defn cons [x y]
  (fn [f]
    (f x y)))

(defn first [coll]
  (coll (fn [x y] x)))

(defn rest [coll]
  (coll (fn [x y] y)))

因此,如果你想要一套用於函數式編程的公理,那么只有一個公式:lambda是最終的公理。 有關如何完成其​​他功能的派生的詳細信息,請參閱以下文章:

  • 經典的Lambda終極論文。
  • 使用Nothing編程 ,這是一種更新的方法。 這使用Ruby語法,但它並不重要,因為它使用的唯一語言功能是lambda。
  • SICP還有一個關於從lambda中獲取car / cdr / cons的部分,作為解釋抽象障礙價值的一部分:只要滿足你已經建立的合同,實現並不重要。 當然,如果您對編程的基礎感興趣,那么SICP通常是一個很好的閱讀。

從評論中可以看出,對這個答案存在很多困惑; 我沒有為以前沒見過的人解釋過它。

我們的想法不是重新實現clojure的所有內置第一/休息功能,這些功能是適用於各種序列的高級多態事物。 相反,我們實現了三個cons / first / rest函數,這些函數一起工作以允許您通過滿足合同來構建集合

(= x (first (cons x y)))
(= y (rest (cons x y)))

可以用lambda構建更復雜的東西,比如clojure的實際第一個/休息,但是你必須首先發明一個完整的類型系統,所以它涉及更多。

這是一個示例repl會話,描述了本練習旨在演示的內容:

(defn cons [x y]
  (fn [f]
    (f x y)))

(defn first [coll]
  (coll (fn [x y] x)))

(defn rest [coll]
  (coll (fn [x y] y)))
user> (def integers (cons 0 (cons 1 (cons 2 (cons 3 nil)))))
#'user/integers
user> integers
#object[user$cons$fn__2108 0x3fb178bd "user$cons$fn__2108@3fb178bd"]
user> (first integers)
0
user> (first (rest (rest integers)))
2

通過了解清單是如何開始cons tructed大多數函數式語言,意思是,為什么它使這么多的意義來看待列表作為firstrest 這種遞歸定義是理解更改它們的遞歸機制的關鍵。

我第一次瀏覽map / filter / fold等的方式實際上是通過haskell,它具有表達事物類型的好處。 這對初學者來說很有意義,至少對我而言。

例如, map有簽名(a -> b) -> [a] -> [b]讀為:如果你有一個函數,它接受一個類型a並將其轉換為類型b ,並給出一個類型列表a ,然后map會簡單地返回一個b類型的列表。

你應該把你的時間在了解一個是fold (包括leftright ),它的reduce是一個類型的世界的一個特例。 一旦你准備好了,我會建議你閱讀關於折疊的普遍性和表現力的好老A教程

我強烈建議您嘗試並實現您提到的所有內容,您對這些基本構建塊及其依賴項的理解將會大大改善。 實現減少(兩者倍)來講recur ,實現map filter take等雙方來講recurreduce

例如,我認為你不能找到一組類似於概率論的簡單公理。 對於概率,只有3個基本公理:

  • 每個事件A的P [A]> = 0
  • P [“任何事件”] = 1
  • 如果A和B互斥,則P [A或B] = P [A] + P [B]

令人驚訝的是,概率和統計中的所有內容都可以從這三個基本假設中得出。

功能編程 ”的定義並不是很明確。 事實上,幾乎每本關於這個主題的書都是從觀察到的,如果你要求100位“專家”來定義函數式編程,那么你將收到100個互不相容的答案。 這句話只是部分開玩笑。

關於函數式編程,你唯一能說的就是它比傳統或“非函數”語言更強調函數。 這實際上更像是函數式語言或函數式編程風格的“目標”,而不是是/否觀察。

功能編程的目標與以往一樣:通過更高的簡單性和可靠性節省成本。 當然,自計算開始以來,每種語言和技術都有相同的游戲計划。 FP的目標主要是通過以下方式實現:

  • 減少可變變量的使用
  • 增加使用功能而不是手動循環

請注意,它表示“減少”和“增加”,而不是“僅”和“從不”。 決定這意味着什么是判斷 - 呼叫,答案將根據手頭的問題和你問的人而改變。

請記住,問題和人員都會隨着時間而變化。 在成本,復雜性,效率,可維護性等方面,今天“最佳”權衡的答案可能不會是一個月或一年中的“最佳”答案,因為問題,人員,工具,硬件,價格等都會發生變化隨着時間的推移。

記住科學校長。 它迫使你嘗試(實驗),而不僅僅是思考它們(理論)。 所以你必須要做一些事情並觀察結果。

在軟件中,這意味着以2種(或更多種)方式解決問題,並比較每種方法的優缺點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM