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

相关问题