首页 > 解决方案 > Haskell 表达类型值之间的关系

问题描述

我是haskell的新手,我开始为自己的“文化”编写以下项目https://owickstrom.github.io/domain-modelling-with-haskell-workshop/,我的第一次尝试是将预算和项目定义为单独的数据类型(如作者所建议的那样),但在处理函数 getBudget 时很快我无法找到一种方法来参考 projectID 字段将给定项目与其预算相关联。[我只是逐渐按照说明并一路创建代码,我个人认为预算应该是项目的“内在”属性,不需要为应该导致尝试2的预算编码创建单独的结构,但是.. .]

尝试1:

data Budget = Budget ProjectID Income Expenditure deriving Show
data Project = SingleP ProjectID Name| GroupP [Project] deriving Show

出于测试目的,我创建了两个“实例”

testProject = SingleP 1 "Haskell workshop"
testBudget = Budget 1 100000.0 50000.0

testProject <-> testBudget 与项目的 ID 相关。我没有设法编写一个函数来获取一个 ID,然后“查找”相应的预算并检索预算数据。如果不这样做,我认为我应该创建一个“嵌入”这样的关系的数据类型(尝试2):

data Budget = Budget Income Expenditure   
data Project = SingleP ProjectID Name Budget ....

然后testProject = SingleP 1 "Haskell worskhop" testBudget

我的问题: - 我是否正确地说不可能编写这种关系,(我怀疑这是由于变量不变性,只是说我无法在 Haskell 中“访问”testBudget)?- 任何这样的“sql'ish”域模型都应该围绕“total”数据类型构建,即一种“封装”关系的数据类型,因为关系不能以功能方式编程。

标签: haskelltypesentity-relationship

解决方案


不,你不对。该功能可以很容易地编码。

例如,您可以从两个列表开始,类型[Budget][Project].

然后使用该模块Data.Map,您可以构建两个字典Map ProjectID BudgetMap ProjectId Project,并在它们上运行您的查找查询。这些将用作两个数据库表。

如果预算表和项目表分开存在,您可以将不同的预算表和项目表配对作为查询函数的参数。

如果您将预算推入您的项目数据类型,您将只有一个表,Map当然也可以将其实现。然后,如果一个项目的预算发生变化,您必须更新该表,即使用该项目的更新条目创建其副本。这也可以通过同一Data.Map模块的功能轻松完成。


推荐阅读