import Control.SetFunctions -- The nodes of a graph data Node = A | B | C | D | E deriving (Eq,Show) -- The edges of a graph next :: Node -> Node next A = B next A = C next B = A next B = C next B = D next C = D next C = E next D = E next E = C succ :: Node -> Node succ A = B ? C succ B = A ? C ? D succ C = D ? E succ D = E succ E = C -- Compute a path from a given node to a target node. pathFromTo :: Node -> Node -> [Node] pathFromTo n1 n2 = extendPath n2 [n1] -- Extends a given path (in reverse order) to a target node. extendPath :: Node -> [Node] -> [Node] extendPath target rpath@(n:_) = if target == n then reverse rpath else extendPath target ((succ n) `consNoCycle` rpath) -- Constrained constructor to construct acyclic lists only: consNoCycle :: Node -> [Node] -> [Node] consNoCycle x xs | all (/= x) xs = x : xs shortestPath :: Node -> Node -> [Node] shortestPath n1 n2 = minValueBy shorter ((set2 pathFromTo) n1 n2) where shorter p1 p2 = compare (length p1) (length p2)