免责声明:以下是一个几乎毫无意义的“绑定节点”技术练习。如果您想要实际使用图形,请使用Fgl。但是,如果您想知道如何在函数式编程中表示循环数据结构,请继续阅读。
在Haskell中表示图形非常容易!
data Vertex a b = Vertex { vdata :: a, edges :: [Edge a b] }
data Edge a b = Edge { edata :: b, src :: Vertex a b, dst :: Vertex a b }
type Myvertex = Vertex String ()
type Myedge = Edge String ()
e :: Myvertex -> Myvertex -> Myedge
e = Edge ()
v :: String -> [Myedge] -> Myvertex
v = Vertex
mygraph5 = map vv [ "one", "two", "three", "four", "five" ] where
vv s = let vk = v s (zipWith e (repeat vk) mygraph5) in vk
这是一种循环、有限、递归、纯函数的数据结构。虽然并不是非常高效或美观,但注意,它没有指针!这里有一个练习:在顶点中包含入边。
data Vertex a b = Vertex {vdata::a, outedges::[Edge a b], inedges::[Edge a b]}
很容易构建一个包含每条边两个(无法区分的)副本的完整图:
mygraph5 = map vv [ "one", "two", "three", "four", "five" ] where
vv s =
let vks = repeat vk
vk = v s (zipWith e vks mygraph5)
(zipWith e mygraph5 vks)
in vk
但是尝试构建一个只有一个副本的副本!(想象一下在e v1 v2
中涉及到一些昂贵的计算。)
let xs = () : xs in xs
将构造一个单元素循环列表,而不是无限重复元素的列表。 - C. A. McCann