在Clojure / Haskell中管理不变量
我一直在比较面向对象和面向对象的方法,而且我不能在功能编程中把我的头放在一件事上 - 在数据结构中保持不变。
例如,想象下面的要求。
我们有一个项目清单,每个项目都有一个任务清单和一个分配成员清单。 每个任务都可以分配一个工作人员,但只能从项目分配成员列表中分配。
我可以想象,如何通过添加所需的检查和异常来在OOP语言中解决此问题(例如在Java中),这将导致我认为更强大的代码。
但是,由于数据与FP中的行为分离,我应该如何解决FP中的相同问题,比如在Clojure或Haskell中?
你的问题是非常普遍的,很多策略可以用来解决相关的问题,但本质上,检查不变量(在运行时)与OOP中的“相等”
assign :: Task -> Worker -> Either String Task
assign task worker =
if not (taskProject task) `containsWorker` worker
then Left "You can't assign..."
else Right $ task { taskWorkers = worker : taskWorkers task }
一种常见的行为是隐藏data
构造函数(如Task
, Worker
和Project
),OOP对象编写private
构造函数。
module Scheduler (
Task -- instead `Task (..)`
, Worker -- instead `Worker (..)`
...
, assign
, createTask
, createWorker
...
) where
(我不知道当前Haskell支持给friend
, protected
,...对手可能不存在,你可以找到很多Haskell模块与Some.Module.Internals.Something
与私人对象)
主要问题是如何构建整个程序以实现所需的行为。
真实世界Haskell是了解这一点的最佳起点,或者如相关问题所建议的那样Haskell中的大规模设计?
另一方面,关于Haskell中的前/后条件,您可以阅读Haskell中的前提条件检查的选项。
在Clojure中,可以在任何函数上指定任意:pre
和:post
条件。 以下是文档中的一个示例:
(defn constrained-sqr [x]
{:pre [(pos? x)]
:post [(> % 16), (< % 225)]}
(* x x))
还有一个非常有趣的图书馆核心。在Clojure中实施契约的合同。
你说数据与FP语言中的行为是“分离的”,但是在Haskell中(我不知道Clojure),你可以很容易地在模块中定义数据结构,使其定义保密,并且只导出函数来操纵数据。
换句话说,Haskell没有(OO风格)类,但它仍然具有封装性。
链接地址: http://www.djcxy.com/p/42877.html上一篇: Managing invariants in Clojure / Haskell
下一篇: Best Practice on design and usage of data type in Haskell