如何在函数式编程语言中实现Rails类型webapp中的“模型”?

在MVC Web开发框架(如Ruby on Rails,Django和CakePHP)中,HTTP请求被路由到控制器,控制器获取通常持久存储到后端数据库存储的对象。 这些对象代表用户,博客post等内容,并且通常在其方法中包含用于权限,获取和/或变异其他对象,validation等的逻辑。

这些框架都非常面向对象。 我最近一直在阅读关于函数式编程的文章,它似乎带来了诸如可测试性,简洁性,模块性等巨大的好处。然而,我见过的函数式编程的大多数例子都实现了诸如quicksort或fibonnacci序列之类的琐碎function,而不是复杂的webapps。 我看了几个“function”的Web框架,他们似乎都很好地实现了视图和控制器,但很大程度上跳过了整个“模型”和“持久性”部分。 (我正在谈论更多像Compojure这样的框架,这些框架应该是纯粹的function,而不是一些方便似乎使用Scala的OO部分用于模型的东西 – 但如果我在这里错了,请纠正我。)

我还没有看到如何使用函数式编程来提供OO编程提供的隐喻,即表映射到对象,以及对象可以提供强大的封装逻辑(如权限和validation)的方法。 此外,使用SQL查询来保存数据的整个概念似乎违反了整个“副作用”概念。 有人可以解释如何在function编程的Web框架中实现“模型”层吗?

不想破坏面向对象的MVC框架 – 我不知道Rails,但Django对我来说是一个很好的软件 – 我不确定对象关系映射是一个特别好的比喻 1

当然,在OO语言中,想要根据对象来考虑表格似乎很自然,但在函数式语言中,根据表格来考虑表格是很自然的。 可以使用代数数据类型(在Haskell和其他静态类型的函数语言中)或映射(也称为字典;将键映射到值的关联结构)轻松表示单行; 然后一个表成为一系列行,毕竟它甚至在数据库级别。 因此,没有从表的DB结构到编程语言中可用的其他构造的特殊映射; 你可以简单地使用两边的桌子。 2

现在这并不意味着有必要使用SQL查询来操纵数据库中的数据,而不是基于varios RDBMS的怪癖的抽象优势。 由于您正在使用Clojure标记,因此您可能对ClojureQL感兴趣, ClojureQL是一种嵌入式DSL,用于以通用方式与各种DB进行通信。 (请注意,它现在正在重新设计。)您可以使用一些此类DSL来提取数据; 使用纯函数操纵如此获得的数据; 然后显示一些结果,并可能将一些数据保留回DB(使用相同的DSL)。


1如果你认为将技术与越南战争进行比较有点极端,我想我同意,但这并不意味着该文章没有很好地描述为什么人们可能不想陷入ORM泥潭。

2请注意,您可以在OO语言中使用相同的方法,并使用与FP语言相同的方式对DB后端进行抽象(请参阅下一段)。 当然,你的MVC框架将不再像Rails那样。

查看Conjure Web应用程序框架 ,以获取如何在函数式编程语言中实现MVC框架的示例。 Conjure使用模型层的clj-record ,它支持关联和validation。