【发布时间】:2011-03-05 21:45:24
【问题描述】:
什么是设计/构造大型函数式程序的好方法,尤其是在 Haskell 中?
我已经阅读了很多教程(Write Yourself a Scheme 是我最喜欢的,Real World Haskell 紧随其后)——但大多数程序都相对较小,而且用途单一。此外,我不认为其中一些特别优雅(例如,WYAS 中的大量查找表)。
我现在想编写更大的程序,有更多的移动部件 - 从各种不同的来源获取数据,清理它,以各种方式处理它,在用户界面中显示它,持久化它,通过网络通信等. 怎样才能最好地构建这样的代码,使其清晰易读、可维护并适应不断变化的需求?
对于大型面向对象的命令式程序,有相当多的文献解决了这些问题。 MVC、设计模式等想法是实现诸如关注点分离和面向对象风格中的可重用性等广泛目标的不错的处方。此外,较新的命令式语言适用于“随成长而设计”的重构风格,在我的新手看来,Haskell 似乎不太适合。
是否有与 Haskell 相当的文献?函数式编程(单子,箭头,应用程序等)中可用的奇异控制结构的动物园如何最好地用于此目的?您可以推荐哪些最佳做法?
谢谢!
编辑(这是唐斯图尔特回答的后续):
@dons 提到:“Monads 以类型捕获关键架构设计。”
我想我的问题是:应该如何考虑用纯函数式语言进行关键架构设计?
考虑几个数据流和几个处理步骤的例子。我可以将数据流的模块化解析器编写为一组数据结构,并且可以将每个处理步骤实现为纯函数。一条数据所需的处理步骤将取决于其价值和其他数据。某些步骤之后应该有一些副作用,例如 GUI 更新或数据库查询。
以一种很好的方式将数据和解析步骤联系起来的“正确”方法是什么?可以编写一个大函数来为各种数据类型做正确的事情。或者可以使用 monad 来跟踪到目前为止已处理的内容,并让每个处理步骤从 monad 状态中获取下一步需要的任何内容。或者可以编写大部分独立的程序并发送消息(我不太喜欢这个选项)。
他链接的幻灯片有一个“我们需要的东西”项目符号:“将设计映射到 types/functions/classes/monads”。成语是什么?:)
【问题讨论】:
-
我认为用函数式语言编写大型程序的核心思想是通过消息传递进行通信的小型、专用和无状态模块。当然,您必须假装一点,因为真正的程序需要状态。我认为这就是 F# 超越 Haskell 的地方。
-
@Chaos 但默认情况下只有 Haskell 强制执行无状态。你别无选择,必须努力在 Haskell 中引入状态(以打破组合性):-)
-
@ChaosPandion:理论上我并不反对。当然,在命令式语言(或围绕消息传递设计的函数式语言)中,我很可能会这样做。但是 Haskell 有其他处理状态的方法,也许它们让我保留了更多的“纯”好处。
-
我在本文档的“设计指南”下写了一点:community.haskell.org/~ndm/downloads/…
-
@JonHarrop 我们不要忘记,虽然 MLOC 在比较类似语言的项目时是一个很好的指标,但对于跨语言比较来说没有多大意义,尤其是像 Haskell 这样代码重用的语言与现有的某些语言相比,模块化更加简单和安全。
标签: haskell functional-programming monads large-scale