{- | 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 = Maybe Lists -> Lists forall a. HasCallStack => Maybe a -> a fromJust (Maybe Lists -> Lists) -> (g -> Maybe Lists) -> g -> Lists forall b c a. (b -> c) -> (a -> b) -> a -> c . (Set Vertex, Set Edge) -> Maybe Lists forall g. Graph g => (Set Vertex, Set Edge) -> Maybe g toGraph ((Set Vertex, Set Edge) -> Maybe Lists) -> (g -> (Set Vertex, Set Edge)) -> g -> Maybe Lists forall b c a. (b -> c) -> (a -> b) -> a -> c . g -> (Set Vertex, Set Edge) forall g. Graph g => g -> (Set Vertex, Set Edge) sets -- | Convert graph to the 'Adjacency' representation. toAdjacency :: g -> Adjacency toAdjacency = Maybe Adjacency -> Adjacency forall a. HasCallStack => Maybe a -> a fromJust (Maybe Adjacency -> Adjacency) -> (g -> Maybe Adjacency) -> g -> Adjacency forall b c a. (b -> c) -> (a -> b) -> a -> c . (Set Vertex, Set Edge) -> Maybe Adjacency forall g. Graph g => (Set Vertex, Set Edge) -> Maybe g toGraph ((Set Vertex, Set Edge) -> Maybe Adjacency) -> (g -> (Set Vertex, Set Edge)) -> g -> Maybe Adjacency forall b c a. (b -> c) -> (a -> b) -> a -> c . g -> (Set Vertex, Set Edge) forall g. Graph g => g -> (Set Vertex, Set Edge) sets -- | Convert graph to the 'Paths' representation. toPaths :: g -> Paths toPaths = Maybe Paths -> Paths forall a. HasCallStack => Maybe a -> a fromJust (Maybe Paths -> Paths) -> (g -> Maybe Paths) -> g -> Paths forall b c a. (b -> c) -> (a -> b) -> a -> c . (Set Vertex, Set Edge) -> Maybe Paths forall g. Graph g => (Set Vertex, Set Edge) -> Maybe g toGraph ((Set Vertex, Set Edge) -> Maybe Paths) -> (g -> (Set Vertex, Set Edge)) -> g -> Maybe Paths forall b c a. (b -> c) -> (a -> b) -> a -> c . g -> (Set Vertex, Set Edge) forall g. Graph g => g -> (Set Vertex, Set Edge) sets -- | Convert graph to the 'G' representation. toG :: g -> G toG = Maybe G -> G forall a. HasCallStack => Maybe a -> a fromJust (Maybe G -> G) -> (g -> Maybe G) -> g -> G forall b c a. (b -> c) -> (a -> b) -> a -> c . (Set Vertex, Set Edge) -> Maybe G forall g. Graph g => (Set Vertex, Set Edge) -> Maybe g toGraph ((Set Vertex, Set Edge) -> Maybe G) -> (g -> (Set Vertex, Set Edge)) -> g -> Maybe G forall b c a. (b -> c) -> (a -> b) -> a -> c . g -> (Set Vertex, Set Edge) 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 = Lists -> Lists forall a. a -> a id instance ConvertibleGraph Adjacency where toAdjacency :: Adjacency -> Adjacency toAdjacency = Adjacency -> Adjacency forall a. a -> a id instance ConvertibleGraph Paths where toPaths :: Paths -> Paths toPaths = Paths -> Paths forall a. a -> a id instance ConvertibleGraph G where toG :: G -> G toG = G -> G forall a. a -> a id