{- | Description: Converting between graph representations Copyright: Copyright (C) 2021 Yoo Chung License: GPL-3.0-or-later Maintainer: dev@chungyc.org Some solutions to "Problems.P80" of Ninety-Nine Haskell "Problems". -} module Solutions.P80 (ConvertibleGraph, toLists, toAdjacency, toPaths, toG) where import Data.Maybe (fromJust) import Problems.Graphs -- | Functions to convert between the different graph representations -- 'Lists', 'Adjacency', 'Paths', and 'G'. class Graph g => ConvertibleGraph g where -- | Convert graph to the 'Lists' representation. toLists :: g -> Lists toLists = forall a. HasCallStack => Maybe a -> a fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c . forall g. Graph g => (Set Vertex, Set Edge) -> Maybe g toGraph forall b c a. (b -> c) -> (a -> b) -> a -> c . forall g. Graph g => g -> (Set Vertex, Set Edge) sets -- | Convert graph to the 'Adjacency' representation. toAdjacency :: g -> Adjacency toAdjacency = forall a. HasCallStack => Maybe a -> a fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c . forall g. Graph g => (Set Vertex, Set Edge) -> Maybe g toGraph forall b c a. (b -> c) -> (a -> b) -> a -> c . forall g. Graph g => g -> (Set Vertex, Set Edge) sets -- | Convert graph to the 'Paths' representation. toPaths :: g -> Paths toPaths = forall a. HasCallStack => Maybe a -> a fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c . forall g. Graph g => (Set Vertex, Set Edge) -> Maybe g toGraph forall b c a. (b -> c) -> (a -> b) -> a -> c . forall g. Graph g => g -> (Set Vertex, Set Edge) sets -- | Convert graph to the 'G' representation. toG :: g -> G toG = forall a. HasCallStack => Maybe a -> a fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c . forall g. Graph g => (Set Vertex, Set Edge) -> Maybe g toGraph forall b c a. (b -> c) -> (a -> b) -> a -> c . forall g. Graph g => g -> (Set Vertex, Set Edge) sets -- All of the above do use 'toGraph' and 'sets', so the solutions are trivial here. -- In essence, it was still an interesting and non-trivial exercise for me, -- because I already did the real work as part of implementing 'toGraph' for -- each of the graph representations. instance ConvertibleGraph Lists where toLists :: Lists -> Lists toLists = forall a. a -> a id instance ConvertibleGraph Adjacency where toAdjacency :: Adjacency -> Adjacency toAdjacency = forall a. a -> a id instance ConvertibleGraph Paths where toPaths :: Paths -> Paths toPaths = forall a. a -> a id instance ConvertibleGraph G where toG :: G -> G toG = forall a. a -> a id