我最近进入了函数式编程(FP)的世界,我想知道如何在功能上思考"适用于中等规模的应用?特别是w.r.t. FP的分析和设计。
通过OOP,我们可以根据对象,属性和关系进行思考。我们使用类和序列图对我们的分析/设计进行建模。但是,在设计FP时,相同的模型似乎不合适。函数式编程的等效建模范例是什么?看来DFD可能很合适,但我可能错了。
例如:我正在考虑设计一个使用Haskell的棋盘游戏Monopoly的模拟,只是为了学习语言。在做OOAD时,你会想到board
包含items
的类,它们附加了属性/方法。您可以在类图中捕获player
和各种其他对象及其关联关系。以及它们在序列图中的相互作用。然而,这些建模范例似乎并不能很好地转换为功能程序。所以只是"如何"你在功能模型?
注意:我正在寻找可以解释如何分析和设计功能程序的具体参考/示例,因为我来自面向对象的思维/建模方式。
答案 0 :(得分:18)
Simon Peyton Jones说:
你写的语言深刻地影响了你的设计 用该语言编写的程序。例如,在OO世界中,很多 人们使用UML绘制设计草图。在Haskell或ML中,一个写入类型 签名代替。功能的初始设计阶段的大部分 程序包括编写类型定义。不过,与UML不同 这个设计被纳入最终产品,并且是 机器检查。
因此,您不必绘制所有花哨的UML图,而是在设计阶段实际编写与undefined
结合的类型定义。
答案 1 :(得分:3)
这些天我的所有节目都包含单人项目。如果我与其他程序员合作开发项目,我认为编写类型定义并使用undefined
将是一个很好的方法。
但我收集你真正想要的是关于你如何学会在功能上思考的一些建议。所以这里有一些想法。
在Haskell中编程时,我会想到我正在编写的程序有两种方式。
如果程序是数学的,我认为程序是一组方程式。
否则,我倾向于将程序视为一个或多个数据转换链。 (所以也许DFD会很有用。)
所以在你的垄断例子中,我的第一个想法是弄清楚我将如何代表董事会的状态(例如,哪些房产有房屋,谁拥有房屋)。然后我可能有一个功能,当有人购买房产时改变董事会,以及玩家可能做的其他事情的其他功能。 (还有用于表示状态的monad,State
和StateT
。我可能会使用它们,如果我觉得它们会使代码更清晰,但我通常会保持基本的开始。)
我最初作为初学者犯下的错误之一就是创建了许多不必要的类和数据类型。
答案 2 :(得分:3)
简短回答:组成较小的程序。
你首先要研究这个问题,然后你开发了一组小的操作(通常以组合器的形式),你认为在这个问题的上下文中有意义,最后你围绕这些操作构建解决方案。我的印象是Hackage上发现的所有软件包都遵循这种方法。
通过这种方式,最终解决方案(通常不是)简单,清晰和优雅。您可以理解您为解决方案选择的上述一系列小型操作非常重要;通过练习,你会发展出明智的选择感受。
我的书建议是Richard Bird的{em>功能算法设计珍珠,Google Books (preview)。在本书中,您将了解函数式编程的计算方法,我认为这是最有价值的。
答案 3 :(得分:2)
您可能感兴趣的两本书:
Structure and Interpretation of Computer Programs - Scheme中CS教科书的经典介绍。我认为对于对FP感兴趣的程序员来说这是必须的。
How to Design Programs - 与SICP相似,略微更现代,专注于设计。这里选择的语言是Racket。
如果您想在Haskell中亲自动手实施项目,我建议Write Yourself a Scheme in 48 Hours,这是一个实现Scheme解释器的精彩教程。 AST操作是FP(特别是Haskell)闪耀的地方,所以我认为编写一个解释器对于新的FP程序员来说是一种很好的体验。
答案 4 :(得分:0)
我对FP vs OO分析和设计辩论的看法如下:
FP中的大多数书籍,就像我之前在其他答案中提到的那些书籍一样,不会向您展示如何设计(又称为分解)复杂的现实问题。他们通常通过非常简短的示例来展示FP的功能(例如,将它们与Craig Larman的Applying UML and Patterns优秀书籍中的示例进行比较,并自行判断)。
对于更接近所谓的面向功能的分析和设计(FOAD)的东西,我建议这些:
DDD,OOAD和FOAD可以用任何一种编程语言来实现,但是某些编程语言提供了使这些方法更容易或更难实现的构造,但是它们是完全实用的。您可以找到许多在FP环境下讨论DDD的资料。
博士艾伦·凯(Alan Kay)谈到了OOP(here)的本质:
对我而言,OOP意味着仅消息传递,本地保留和保护以及 隐藏状态过程,并限制所有事物的后期绑定。它 可以在Smalltalk和LISP中完成。可能还有其他系统 在这种情况下是可能的,但是我不知道它们。
在此声明之后,Erlang的创造者之一Joe Armstrong是一种在行业中具有重要用途的FP语言(例如WhatsApp),他认为Erlang也许是(see this interview also featuring Ralph Johnson)之外最面向对象的语言。
另外,有人说Erlang是捕捉OO编程本质的最佳语言:the passing of messages between objects。
希望这会有所帮助。
答案 5 :(得分:0)
我只能从Erlang OTP的角度发言。我们认为流程具有状态和功能。因此,在该状态下,进程将具有所有“变量”,并且处理程序函数会对进程在其消息队列中接收的数据做出反应。它们对接收到的数据起作用,可能会更改自己的状态,可能返回一些数据和/或产生一些副作用。该状态可以存储在地图或记录或任何其他有效数据类型中。通常,我们定义一个称为state()或loopData()的记录。