Несколько других кратко упомянули fgl
и алгоритмы индуктивных графов и функциональных графов Мартина Эрвига , но, вероятно, стоит написать ответ, который фактически дает представление о типах данных, лежащих в основе подхода индуктивного представления,
В своей статье Эрвиг представляет следующие типы:
type Node = Int
type Adj b = [(b, Node)]
type Context a b = (Adj b, Node, a, Adj b)
data Graph a b = Empty | Context a b & Graph a b
(Представление в fgl
немного отличается и хорошо использует классы типов - но идея по сути та же самая.)
Эрвиг описывает мультиграф, в котором узлы и ребра имеют метки, и в котором все ребра направлены.A Node
имеет метку какого-то типа a
;ребро имеет метку какого-то типа b
.Context
- это просто (1) список помеченных ребер, указывающих на конкретный узел, (2) рассматриваемый узел, (3) метка узла и (4) список помеченных реберуказывая от на узел.Graph
может быть затем индуктивно воспринят либо как Empty
, либо как Context
, объединенный (с &
) в существующий Graph
.
Как отмечает Эрвиг, мы не можемсвободно генерируйте Graph
с Empty
и &
, как мы могли бы создать список с конструкторами Cons
и Nil
, или Tree
с Leaf
и Branch
.Кроме того, в отличие от списков (как уже упоминали другие), не будет никакого канонического представления Graph
.Это принципиальные различия.
Тем не менее, то, что делает это представление настолько мощным и похожим на типичные представления списков и деревьев на Хаскеле, состоит в том, что тип данных Graph
здесь индуктивно определен ,Тот факт, что список является индуктивно определенным, позволяет нам так кратко сопоставлять шаблоны, обрабатывать отдельный элемент и рекурсивно обрабатывать остальную часть списка;в равной степени индуктивное представление Эрвига позволяет нам рекурсивно обрабатывать граф по одному Context
за раз.Это представление графа поддается простому определению способа отображения на графе (gmap
), а также способа выполнения неупорядоченных сгибов над графами (ufold
).
Другие комментарии на этой странице великолепны.Однако основная причина, по которой я написал этот ответ, заключается в том, что когда я читаю фразы типа «графы не алгебраические», я боюсь, что у некоторых читателей неизбежно возникнет (ошибочное) впечатление, что никто не нашел хорошего способа представления графиков.в Haskell таким образом, который позволяет сопоставлять с ними шаблоны, отображать их, сворачивать их или вообще делать что-то классное, функциональное, что мы привыкли делать со списками и деревьями.