3

我对一些高级函数式编程思想很陌生,特别是:如何使用不可变数据。数据结构通常是复合的,由较小的数据结构组成。例如,如果我们有一个家庭集合,它由一个家庭的所有成员组成。我们可以构建家庭:

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但出于什么目的?由于所有对象都只是快照,我看不到保留引用的意义。状态变化已经被抽象掉了,所以我们不打算使用观察者模式。因此,像 GUI 这样关心状态变化的依赖事物是如何处理的?为了使事物保持同步,观察的功能替代方法是什么?我不认为对象本身在渲染自己方面有任何业务。功能程序如何处理保持单页 webapp GUI 的状态同步?

物有所值Rich Hickey 的演讲启发了我探索函数式编程。我得到了他的概念,但我很难跳到一个实际的实现(在 JavaScript 中)。

4

1 回答 1

2

在您的示例中,Family应该是不可变的。所以每次调用都add必须返回一个全新的对象,该对象基于现有对象的内容(它们本身是不可变的,所以复制它们不是问题)加上新的东西。同样,set您调用的Fred必须返回一个基于 Fred 但姓氏不同的全新家庭成员。(因此里面原来的FredFlintstones根本没有改变。)

这种函数式风格的优点是,一旦你得到一个对象的引用,你就知道它不会改变。如果它在构建时是有效的,您不必继续检查它是否仍然有效。任何您都可以将对象从代码中传递出去,而无需先克隆它以保护您的内部副本不被更改。

如果你想了解更多关于函数式编程的知识,你最好尝试一门纯粹的函数式语言,比如 Haskell 或 F#;尝试在 JavaScript 中进行函数式编程可能会令人困惑。

于 2013-04-12T20:39:18.643 回答