使用代数数据类型表示haskell中的树或列表很容易.但是你会怎么用印刷术来表示图形呢?看来你需要有指针.我猜你可以有类似的东西
type Nodetag = String
type Neighbours = [Nodetag]
data Node a = Node a Nodetag Neighbours
Run Code Online (Sandbox Code Playgroud)
这是可行的.然而感觉有点脱钩; 结构中不同节点之间的链接并不真正"感觉"像列表中当前上一个和下一个元素之间的链接一样,或者树中节点的父节点和子节点之间的链接.我有一种预感,即在我定义的图形上进行代数操作会受到通过标签系统引入的间接级别的阻碍.
主要是这种怀疑的感觉和不雅的感觉使我提出这个问题.在Haskell中定义图形是否有更好/更优化的方式?或者我偶然发现了本质上坚硬/根本的东西?递归数据结构很好,但这似乎是另一回事.自引用数据结构,与树和列表的自引用方式不同.它就像列表和树在类型级别是自引用的,但是图形在值级别是自引用的.
那真正发生了什么?
haskell types functional-programming graph algebraic-data-types
我发现想要在我的功能程序中建模关系数据是很常见的.例如,在开发网站时,我可能希望使用以下数据结构来存储有关我的用户的信息:
data User = User
{ name :: String
, birthDate :: Date
}
Run Code Online (Sandbox Code Playgroud)
接下来,我想存储有关用户在我的网站上发布的消息的数据:
data Message = Message
{ user :: User
, timestamp :: Date
, content :: String
}
Run Code Online (Sandbox Code Playgroud)
此数据结构存在多个问题:
User是脆弱的 - 您可能忘记更新User数据结构中的所有事件.这些问题是可管理的,而我们的数据可以表示为树.例如,您可以像这样重构:
data User = User
{ name :: String
, birthDate :: Date
, messages :: [(String, Date)] -- you get the idea
}
Run Code Online (Sandbox Code Playgroud)
但是,可以将数据整形为DAG(想象任何多对多关系),甚至可以作为一般图形(好的,也许不是).在这种情况下,我倾向于通过在Maps中存储我的数据来模拟关系数据库:
newtype Id a = Id Integer
type Table a = …Run Code Online (Sandbox Code Playgroud)