Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在haskell中构建图形结构_Haskell - Fatal编程技术网

在haskell中构建图形结构

在haskell中构建图形结构,haskell,Haskell,我正在为关系数据库的类型信息建模。我想构建以下图表: 顶点是表 对于A中的每一列,表A到表B之间都存在一条边,该列是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

我正在为关系数据库的类型信息建模。我想构建以下图表:

  • 顶点是表

  • 对于A中的每一列,表A到表B之间都存在一条边,该列是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
    的信息。如果未找到,则输入数据不一致,是一个错误


    这在带有引用的命令式语言中相当简单。然而,在哈斯克尔,我想不出解决这个问题的办法。据我所知,这看起来很适合“打结”的模式,但我似乎无法将我的头围绕它。如何编写此函数?

    我们可以通过以下方式打结:

    convDBInfo :: DBInfo -> SafeDBInfo
    convDBInfo dbi = safeDbi where
      safeDbi = H.map (H.map go) dbi
      go (CIFKey colName tblName) = SCIFKey colName $ safeDbi H.! tblName
      go (CISimple colName)       = SCISimple colName
    
    我们通过映射输入中的列条目来获得
    safeDbi
    。重要的一点是,我们从
    go
    定义中的
    safeDbi
    中查找表,因此
    SCIFKey
    -s中的表将来自生成的hashmap

    例如:

    foo :: DBInfo
    foo = H.fromList [
      ("table1", H.fromList [
           ("col1", CIFKey "a" "table2")
           ]),
      ("table2", H.fromList [
           ("col2", CIFKey "b" "table1")
           ])
      ]
    
    bar = convDBInfo foo
    SCIFKey _ tbl2 = (bar H.! "table1") H.! "col1"
    SCIFKey name _ = tbl2 H.! "col2"
    -- name == "b"
    

    请注意,尽管棘手的数据结构通常不便于使用,因为它们与懒惰的无限结构无法区分,所以在打印、序列化或比较它们时,我们必须额外考虑它。大多数情况下,显式键控图形更易于使用,性能也不会差很多。

    对不起,convDBInfo应该做什么?对不起,我不清楚。编辑以添加信息。如果您知道不会出现错误,为什么需要返回
    ?从
    DBInfo
    查找
    t
    可能是失败的(
    可能是TableInfo
    ),即使不会发生。为什么不使用HashMap的
    foldWithKey