liveBook · Manning

Node

As explained in Learn Haskell by Example

A node is an entity represented as a vertex in a graph and connected to zero or more other nodes.

A node is one item in a graph. Edges connect nodes, so a path is a sequence of nodes joined by valid connections. In a word-ladder graph, each English word is a node, and an edge represents one allowed transformation between words. Finding a ladder from cat to dog becomes finding a path through those nodes. section 5.1.1

Figure 5.2 A ladder graph for a selection of English words
figure

The ladder graph makes nodes visible as words and shows how edges provide alternative routes between a start word and an end word. section 5.1.1

Nodes do not prescribe a single Haskell value type. A graph can be polymorphic, allowing its nodes to be words, numbers, or another type chosen by the program. For the word game, the useful design question is not just what a node is, but which nodes it connects to and how those connections support shortest-path search. section 5.1.1

For a directed graph, a practical representation maps each node to a list of its connected child nodes. The node is the map key; its children are the values associated with that key. A node without an entry is treated as having no connected nodes, so looking it up returns an empty list. section 5.3.1

Adding and querying nodes

Adding the edge (3,2) records node 2 among node 3’s children. Adding (3,1) gives node 3 the children [2,1]. Querying children 2 returns [] until an edge beginning at node 2 is added. When adding an edge to an existing node, duplicate children are removed with nub. section 5.3.1

Listing 5.7 Functions for adding edges to a directed graph and retrieving connected nodes
import qualified Data.List as L    #1

...

addEdge :: (Eq a) => (a, a) -> DiGraph a -> DiGraph a
addEdge (node, child) = M.alter insertEdge node    #2
  where
    insertEdge Nothing = Just [child]     #3
    insertEdge (Just nodes) =
      Just (L.nub (child : nodes))     #4

addEdges :: (Eq a) => [(a, a)] -> DiGraph a -> DiGraph a
addEdges [] graph = graph                                                 #5
addEdges (edge : edges) graph = addEdge edge (addEdges edges graph)   #6

buildDiGraph :: (Eq a) => [(a, [a])] -> DiGraph a
buildDiGraph nodes = go nodes M.empty
  where
    go [] graph = graph                                                  
    go ((key, value) : xs) graph = M.insert key value
 (go xs graph)                   #7

children :: (Eq a) => a -> DiGraph a -> [a]
children = M.findWithDefault []    #8

This implementation shows nodes as keys in a directed adjacency map, with addEdge, addEdges, buildDiGraph, and children defining the main operations. section 5.3.1

Adding an edge requires handling two cases: the starting node may be absent, or it may already have a child list. The underlying alter operation passes Nothing for a missing key and Just value for an existing mapping. Its result can keep, add, replace, or remove a node’s mapping without mutating the associative list. section 5.2

How Learn Haskell by Example covers it

How deep it goes
Defines nodes through graph representations and implements directed-node lookup and edge insertion, while deferring shortest-path algorithm details.
Examples
Uses English words in a ladder graph and integer nodes queried after adding directed edges.
What it assumes
Introduces graph nodes and edges from a word-game problem while using Haskell types, maps, lists, and Maybe in the implementation.
What you can do after
Build it from scratch as a directed adjacency map with functions to add edges and retrieve connected nodes.
How it connects
Connects nodes with edges, paths, directed graphs, adjacency maps, polymorphic types, associative lists, and Maybe.

Also explained in

Compare how 19 books explain node →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.