【发布时间】:2015-12-15 19:49:14
【问题描述】:
我正在对关系数据库的类型信息进行建模。我想构建以下图表:
顶点是表格。
对于 A 中作为 B 的外键的每一列,从表 A 到表 B 都存在一条边。
这是我用于构建图表的初始数据。
newtype TableName = TableName T.Text
newtype ColName = ColName T.Text
newtype ColType = ColType T.Text
type DBInfo = H.HashMap TableName TableInfo
type TableInfo = H.HashMap ColName ColInfo
data ColInfo = CISimple ColType
-- Forms the basis for building the graph
| CIFKey ColType TableName -- col type, referenced table
getDBInfo :: IO (DBInfo)
这些是我期望的图形结构类型。
data SafeColInfo = SCISimple ColType
-- This captures an edge between two tables
| SCIFKey ColType SafeTableInfo
type SafeTableInfo = H.HashMap TableName SafeColInfo
type SafeDBInfo = ..
我想写这个函数:
convDBInfo :: DBInfo -> Either String SafeDBInfo
convDBInfo 应该构建上图。通过在DBInfo 中查找t 可以找到任何外键(CIFKey ctype t) 中有关t 的信息。如果没有找到,则输入数据不一致,是错误的。
这在带有引用的命令式语言中相当简单。但是,我想不出在 Haskell 中解决这个问题的方法。据我了解,这看起来很适合“打结”范式,但我似乎无法理解它。这个函数怎么写?
【问题讨论】:
-
抱歉,
convDBInfo该怎么办? -
对不起,我不清楚。编辑添加信息。
-
如果知道不会出错,为什么还要返回
Either? -
来自
DBInfo的t中的lookup可能是失败(Maybe TableInfo),即使它不会发生。 -
为什么不用HashMap的
foldWithKey?
标签: haskell