3

我是一些高級函數式編程思想的新手,特別是:如何使用不可變數據。數據結構通常是由較小的數據結構組成的組合。例如,如果我們有一個由家庭所有成員組成的家庭收藏。我們可以構建家庭:FP:在沒有實際狀態變化的情況下反映狀態?

var flintstones = new Family(). 
    add(new Member({name: 'Fred'})). //returns new instance of family 
    add(new Member({name: 'Wilma'}). // " 
    add(new Member({name: 'Pebbles'})); // " 
var fred = flintstones.get({name: 'Fred'}).set({lname: 'Flintstone'}); 
flintstones = fred.family(); //new instance of family with latest fred. 

注意如何改變fred實際上並沒有改變flintstones。我可以抓住一個新的參考flintstones但爲了什麼目的?由於所有對象都僅僅是快照,我無法看到保留引用的重點。狀態變化已被抽象出來,所以我們不會使用Observer模式。因此,如何處理像關心狀態變化的圖形用戶界面這樣的依賴項呢?什麼是觀察的功能選擇,以保持同步?我不認爲這些對象本身就有任何業務呈現自己。功能程序如何處理單頁面web應用程序界面GUI的狀態保持同步?

對於什麼是值得Rich Hickey's talks激勵我去探索函數式編程。我明白了他的觀點,但我正在努力實現一個實際的實現(使用JavaScript)。

+0

不知道我得到了你的問題:這是一個面向對象的方法,而不是一個函數式編程的。你在問如何以更實用的方式轉換它? – ZER0

+0

從我一直在閱讀的內容(尤其是Matthew Strawbridge在他的評論中提供的鏈接),這更多的是關於*反應*而不是*功能*編程。 – bfavaretto

+0

我知道持久數據結構是不可變的。我認爲我並不瞭解的是,國家管理層 - 知道Wilma在與Fred結婚時改變了她的婚前姓名 - 仍然要求程序員管理目前狀態的Wilma的引用(某處)。在某個地方,仍然有一個威爾瑪Slaghoople,但我們目前的參考不再指向它。 – Mario

回答

2

在你的榜樣,Family應該是一成不變的。因此,每次調用add都必須返回一個基於現有對象內容的全新對象(它們本身是不可變的,因此複製它們不是問題)加上新事物。同樣,set你打電話Fred必須返回基於弗雷德但使用不同的姓氏一個全新的家庭成員。 (因此原來Fred裏面的Flintstones根本沒有改變。)

這種功能風格的優點是,一旦你有一個對象的引用,你就知道它不會改變。如果它在構建時有效,則不必檢查它是否仍然有效。任何你可以將對象從你的代碼中移出來,而不必先克隆它,以保護你的內部副本不被改變。

如果您想了解更多關於函數式編程,你可能會更好嘗試一種純粹功能的語言如Haskell中或F#;試圖在JavaScript中進行函數式編程可能會令人困惑。

+0

我瞭解新事物的實例正在創建(lambda微積分,我認爲它被稱爲),但我缺少的是如何在GUI中反映更改。 – Mario

+0

它的細做'變種打火石= fred.family();'(即更新的變量是一些對象點本身並不構件數據在一個新的對象)。你不需要一個新的變量。因此,對於GUI,您只需告訴新組件樹的根目錄即可自行更新。 –

+0

讓我改說一下。你能否在GUI中顯示反映對數據更改的假設代碼?只需幾行(如果需要,編輯您的答案)。 – Mario

相關問題