从编程生涯的第一天开始,我开始使用面向对象编程。但是,我有兴趣学习其他范例(我在这里说了很多次这是一件好事,但我没有时间去做)。我想我不仅准备好了,而且还有时间,所以我将用F#开始函数式编程。
但是,我不确定如何构建更少的设计应用程序。我已经习惯了OO编程中的每类文件和类名词/函数动词。您如何设计和构建功能性应用程序?
答案 0 :(得分:19)
阅读SICP。
此外,还有一个PDF Version。
答案 1 :(得分:13)
您可能想查看我最近的博客文章:How does functional programming affect the structure of your code?
在较高的层面上,OO设计方法对于构建F#程序仍然非常有用,但是当你降低到较低级别时,你会发现这种情况会破坏(规则的更多例外)。在物理层面,“每个文件一个类”在所有情况下都不起作用,因为需要在同一个文件中定义相互递归类型(类型 Class1 = ... 和 Class2 = ...),并且您的一些代码可能驻留在未绑定到特定类的“自由”函数中(这就是F#“模块”的优点)。 F#中的文件排序约束也会迫使您批判性地思考程序中类型之间的依赖关系;这是一把双刃剑,因为它可能需要更多的工作/思考来解开高级别的依赖关系,但会产生的程序组织方式总是让它们变得平易近人(因为最原始的实体总是先行,你可以总是从“从上到下”阅读一个程序并逐个引入新的东西,而不是只是开始查看一个充满代码文件的目录而不知道“从哪里开始”。
答案 2 :(得分:6)
How to Design Programs就是这个(令人厌烦的长度,使用Scheme代替F#,但原则仍然存在)。简而言之,您的代码镜像您的数据类型;这个想法可以追溯到老式的“结构化编程”,只有函数式编程更加明确,并且具有更高级的数据类型。
答案 3 :(得分:5)
鉴于现代函数语言(即不是lisps)默认使用早期绑定的多态函数(高效),并且面向对象只是一种安排具有多态函数的特定方式,如果你的话,它并没有真正的不同知道如何设计正确的封装类。
Lisps使用后期绑定来实现类似的效果。说实话,没有太大的区别,除了你没有明确地声明类型的结构。
如果您已经使用C ++模板函数进行了大量编程,那么您可能已经有了一个想法。
在任何情况下,答案都是小“类”,而不是修改内部状态,你必须返回一个具有不同状态的新版本。
答案 4 :(得分:2)
F#为大规模结构化编程(例如接口)提供了传统的OO方法,并没有尝试提供像OCaml这样的语言(例如仿函数)开创的实验方法。
因此,F#程序的大规模结构与C#程序的结构基本相同。
答案 5 :(得分:1)
功能性编程肯定是一种不同的范例。也许最简单的方法就是坚持使用流程图来设计设计。每个函数都是不同的,没有继承,没有多态,不同。数据从函数传递到函数以进行删除,更新,插入和创建新数据。
答案 6 :(得分:1)
关于构建功能程序:
虽然OO语言使用类构造代码,但函数式语言使用模块构造代码。对象包含状态和方法,模块包含数据类型和函数。在这两种情况下,结构单元将数据类型与相关行为组合在一起。这两种范例都有构建和实施抽象障碍的工具。
我强烈建议您选择一种您熟悉的函数式编程语言(F#,OCaml,Haskell或Scheme),并仔细研究其标准库的结构。
例如,将.NET中的OCaml Stack模块与System.Collections.Generic.Stack或Java中的类似集合进行比较。
答案 7 :(得分:-1)
这完全是关于纯函数以及如何组合它们来构建更大的抽象。这实际上是一个需要robust mathematical background的难题。幸运的是,有几种模式可以进行深入的正式和实际研究。在Functional and Reactive Domain Modeling Debasish Ghosh进一步探讨了这个主题,并汇总了几个应用纯函数模式的实际场景:
功能和反应域建模教会您如何思考 纯函数方面的域模型以及如何将它们组合成 建立更大的抽象。您将从基础开始 功能编程逐步向先进概念发展 以及实现复杂域模型时需要了解的模式。 这本书演示了高级FP模式如代数数据 类型,基于类型的设计,以及副作用的隔离可以使 你的模型构成了可读性和可验证性。