diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -7,6 +7,18 @@
 The following is information about what major changes have gone into
 each release.
 
+Changes in 2999.18.1.0
+----------------------
+
+* Monadic graphs can now have edges to and from lists of nodes, as
+  requested by **Harold Carr**.
+
+* Compatible with GHC-8.* pre-releases.
+
+    - Please note that there is currently a warning emitted on
+      compilation by GHC-8.*; this has been reported
+      [here](https://ghc.haskell.org/trac/ghc/ticket/11822).
+
 Changes in 2999.18.0.2
 ----------------------
 
diff --git a/Data/GraphViz/Attributes/Colors.hs b/Data/GraphViz/Attributes/Colors.hs
--- a/Data/GraphViz/Attributes/Colors.hs
+++ b/Data/GraphViz/Attributes/Colors.hs
@@ -304,7 +304,7 @@
       cs = colorScheme c
       lv = fl c
 
-parseNamedColor :: (NamedColor nc, ParseDot lv)
+parseNamedColor :: (ParseDot lv)
                    => (ColorScheme -> Maybe cs) -> Parse cs -> (cs -> Bool)
                    -> (cs -> lv -> nc) -> Bool -> Parse nc
 parseNamedColor gcs parseCS vcs mkC q
diff --git a/Data/GraphViz/Commands/IO.hs b/Data/GraphViz/Commands/IO.hs
--- a/Data/GraphViz/Commands/IO.hs
+++ b/Data/GraphViz/Commands/IO.hs
@@ -104,8 +104,7 @@
 hPutCompactDot :: (PrintDotRepr dg n) => Handle -> dg n -> IO ()
 hPutCompactDot = toHandle renderCompactDot
 
-toHandle        :: (PrintDotRepr dg n) => (dg n -> Text) -> Handle -> dg n
-                   -> IO ()
+toHandle        :: (dg n -> Text) -> Handle -> dg n -> IO ()
 toHandle f h dg = do B.hPutStr h . T.encodeUtf8 $ f dg
                      hPutChar h '\n'
 
diff --git a/Data/GraphViz/Types.hs b/Data/GraphViz/Types.hs
--- a/Data/GraphViz/Types.hs
+++ b/Data/GraphViz/Types.hs
@@ -182,7 +182,7 @@
   -- | Change the node values.  This function is assumed to be
   --   /injective/, otherwise the resulting graph will not be
   --   identical to the original (modulo labels).
-  mapDotGraph :: (Ord n', DotRepr dg n') => (n -> n') -> dg n -> dg n'
+  mapDotGraph :: (DotRepr dg n') => (n -> n') -> dg n -> dg n'
 
   -- | Return information on all the clusters contained within this
   --   'DotRepr', as well as the top-level 'GraphAttrs' for the
diff --git a/Data/GraphViz/Types/Graph.hs b/Data/GraphViz/Types/Graph.hs
--- a/Data/GraphViz/Types/Graph.hs
+++ b/Data/GraphViz/Types/Graph.hs
@@ -140,7 +140,7 @@
 
 -- | It should be safe to substitute 'unsafeFromCanonical' for
 --   'fromCanonical' in the output of this.
-instance (Ord n, Show n) => Show (DotGraph n) where
+instance (Show n) => Show (DotGraph n) where
   showsPrec d dg = showParen (d > 10) $
                    showString "fromCanonical " . shows (toCanonical dg)
 
@@ -347,7 +347,7 @@
 
 -- | Convert this DotGraph into canonical form.  All edges are found
 --   in the outer graph rather than in clusters.
-toCanonical :: (Ord n) => DotGraph n -> C.DotGraph n
+toCanonical :: DotGraph n -> C.DotGraph n
 toCanonical dg = C.DotGraph { C.strictGraph     = strictGraph dg
                             , C.directedGraph   = directedGraph dg
                             , C.graphID         = graphID dg
@@ -452,7 +452,7 @@
 -- | Delete the specified cluster, and makes any clusters or nodes
 --   within it be in its root cluster (or the overall graph if
 --   required).
-deleteCluster      :: (Ord n) => GraphID -> DotGraph n -> DotGraph n
+deleteCluster      :: GraphID -> DotGraph n -> DotGraph n
 deleteCluster c dg = withValues (M.map adjNode)
                      . withClusters (M.map adjCluster . M.delete c)
                      $ dg
@@ -468,7 +468,7 @@
     adjCluster ci = ci { parentCluster = adjParent $ parentCluster ci }
 
 -- | Remove clusters with no sub-clusters and no nodes within them.
-removeEmptyClusters :: (Ord n) => DotGraph n -> DotGraph n
+removeEmptyClusters :: DotGraph n -> DotGraph n
 removeEmptyClusters dg = dg { clusters = cM' }
   where
     cM = clusters dg
@@ -533,8 +533,7 @@
     sucs = emToDE (DotEdge n) $ _successors ni
     preds = emToDE (`DotEdge` n) $ n `M.delete` _predecessors ni
 
-emToDE :: (Ord n) => (n -> Attributes -> DotEdge n)
-          -> EdgeMap n -> [DotEdge n]
+emToDE :: (n -> Attributes -> DotEdge n) -> EdgeMap n -> [DotEdge n]
 emToDE f = map (uncurry f) . fromMap
 
 -- | Which cluster (or the root graph) is this cluster in?
@@ -580,7 +579,7 @@
 instance (Ord n, PrintDot n, ParseDot n) => PPDotRepr DotGraph n
 
 -- | Uses the PrintDot instance for canonical 'C.DotGraph's.
-instance (Ord n, PrintDot n) => PrintDot (DotGraph n) where
+instance (PrintDot n) => PrintDot (DotGraph n) where
   unqtDot = unqtDot . toCanonical
 
 -- | Uses the ParseDot instance for generalised 'G.DotGraph's.
@@ -670,7 +669,7 @@
     t' = liftA2 (,) t edgeAttributes
     eM = M.fromList . groupSortCollectBy fst snd
 
-mapNs :: (Ord n, Ord n') => (n -> n') -> DotGraph n -> DotGraph n'
+mapNs :: (Ord n') => (n -> n') -> DotGraph n -> DotGraph n'
 mapNs f (DG st d as mid cs vs) = DG st d as mid cs
                                  $ mapNM vs
   where
@@ -695,8 +694,7 @@
                 (p' Seq.:> _) -> p'
                 _             -> Seq.empty
 
-getNodeInfo             :: (Ord n) => Bool -> DotGraph n
-                           -> NodeLookup n
+getNodeInfo             :: Bool -> DotGraph n -> NodeLookup n
 getNodeInfo withGlob dg = M.map toLookup ns
   where
     (gGlob, aM) = globAttrMap nodeAs dg
@@ -713,7 +711,7 @@
         as' | withGlob  = unSame $ toSAttr as `S.union` pAs
             | otherwise = as
 
-getEdgeInfo             :: (Ord n) => Bool -> DotGraph n -> [DotEdge n]
+getEdgeInfo             :: Bool -> DotGraph n -> [DotEdge n]
 getEdgeInfo withGlob dg = concatMap (uncurry mkDotEdges) es
   where
     gGlob = edgeAs $ graphAttrs dg
@@ -761,8 +759,7 @@
 
 -- -----------------------------------------------------------------------------
 
-withValues      :: (Ord n) => (NodeMap n -> NodeMap n)
-                   -> DotGraph n -> DotGraph n
+withValues      :: (NodeMap n -> NodeMap n) -> DotGraph n -> DotGraph n
 withValues f dg = dg { values = f $ values dg }
 
 withClusters      :: (Map GraphID ClusterInfo -> Map GraphID ClusterInfo)
@@ -781,10 +778,10 @@
                               , EdgeAttrs  $ unSame ea
                               ]
 
-niSucc      :: (Ord n) => (EdgeMap n -> EdgeMap n) -> NodeInfo n -> NodeInfo n
+niSucc      :: (EdgeMap n -> EdgeMap n) -> NodeInfo n -> NodeInfo n
 niSucc f ni = ni { _successors = f $ _successors ni }
 
-niPred      :: (Ord n) => (EdgeMap n -> EdgeMap n) -> NodeInfo n -> NodeInfo n
+niPred      :: (EdgeMap n -> EdgeMap n) -> NodeInfo n -> NodeInfo n
 niPred f ni = ni { _predecessors = f $ _predecessors ni }
 
 toMap :: (Ord n) => [(n, Attributes)] -> EdgeMap n
diff --git a/Data/GraphViz/Types/Monadic.hs b/Data/GraphViz/Types/Monadic.hs
--- a/Data/GraphViz/Types/Monadic.hs
+++ b/Data/GraphViz/Types/Monadic.hs
@@ -70,6 +70,7 @@
        , node
        , node'
          -- ** Edges
+       , NodeList (..)
        , edge
        , (-->)
        , (<->)
@@ -211,18 +212,29 @@
 -- -----------------------------------------------------------------------------
 -- Edges
 
+-- | A list of nodes to serve as edge end-points.
+class NodeList n nl where
+  toNodeList :: nl -> [n]
+
+instance NodeList n [n] where
+  toNodeList = id
+
+instance NodeList n n where
+  toNodeList = (:[])
+
 -- | Add an edge to the graph.
-edge     :: n -> n -> Attributes -> Dot n
-edge f t = tellStmt . ME . DotEdge f t
+edge     :: (NodeList n f, NodeList n t) => f -> t -> Attributes -> Dot n
+edge fl tl as = mapM_ (tellStmt . ME)
+                      [ DotEdge f t as | f <- toNodeList fl, t <- toNodeList tl ]
 
 -- | Add an edge with no attributes.
-(-->) :: n -> n -> Dot n
+(-->) :: (NodeList n f, NodeList n t) => f -> t -> Dot n
 f --> t = edge f t []
 
 infixr 9 -->
 
 -- | An alias for '-->' to make edges look more undirected.
-(<->) :: n -> n -> Dot n
+(<->) :: (NodeList n f, NodeList n t) => f -> t -> Dot n
 (<->) = (-->)
 
 infixr 9 <->
diff --git a/Data/GraphViz/Types/State.hs b/Data/GraphViz/Types/State.hs
--- a/Data/GraphViz/Types/State.hs
+++ b/Data/GraphViz/Types/State.hs
@@ -168,10 +168,10 @@
 
 type NodeState n a = GVState (NodeLookup' n) a
 
-toDotNodes :: (Ord n) => NodeLookup n -> [DotNode n]
+toDotNodes :: NodeLookup n -> [DotNode n]
 toDotNodes = map (\(n,(_,as)) -> DotNode n as) . Map.assocs
 
-getNodeLookup       :: (Ord n) => Bool -> NodeState n a -> NodeLookup n
+getNodeLookup       :: Bool -> NodeState n a -> NodeLookup n
 getNodeLookup addGs = Map.map combine . value . (`execState` initState)
   where
     initState = SV Set.empty addGs Seq.empty Map.empty
diff --git a/graphviz.cabal b/graphviz.cabal
--- a/graphviz.cabal
+++ b/graphviz.cabal
@@ -1,5 +1,5 @@
 Name:               graphviz
-Version:            2999.18.0.2
+Version:            2999.18.1.0
 Stability:          Beta
 Synopsis:           Bindings to Graphviz for graph visualisation.
 Description: {
@@ -39,7 +39,7 @@
 Maintainer:         Ivan.Miljenovic@gmail.com
 Build-Type:         Simple
 Tested-With:        GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4,
-                    GHC == 7.10.2, GHC == 7.11.*
+                    GHC == 7.10.2, GHC == 8.0.1, GHC == 8.1.*
 Cabal-Version:      >= 1.14
 Extra-Source-Files: TODO.md
                     Changelog.md
@@ -65,10 +65,10 @@
                            temporary >=1.1 && <1.3,
                            fgl >= 5.4 && < 5.6,
                            filepath,
-                           polyparse >=1.9 && <1.12,
+                           polyparse >=1.9 && <1.13,
                            bytestring >= 0.9 && < 0.11,
                            colour == 2.3.*,
-                           transformers >= 0.2 && < 0.5,
+                           transformers >= 0.2 && < 0.6,
                            text,
                            wl-pprint-text >= 1.1.0.0 && < 1.2.0.0,
                            dlist >= 0.5 && < 0.8
@@ -112,8 +112,6 @@
 
         if impl(ghc >= 6.12.1)
            Ghc-Options: -fno-warn-unused-do-bind
-
-        Ghc-Prof-Options:  -prof
 }
 
 Test-Suite graphviz-testsuite {
@@ -152,7 +150,7 @@
         if impl(ghc >= 6.12.1)
            Ghc-Options: -fno-warn-unused-do-bind
 
-        GHC-Prof-Options: -caf-all -rtsopts
+        GHC-Prof-Options: -rtsopts
 }
 
 Benchmark graphviz-printparse {
@@ -176,7 +174,7 @@
         if impl(ghc >= 6.12.1)
            Ghc-Options: -fno-warn-unused-do-bind
 
-        GHC-Prof-Options: -caf-all -rtsopts
+        GHC-Prof-Options: -rtsopts
 }
 
 Executable graphviz-testparsing {
@@ -200,5 +198,5 @@
 
         Ghc-Options: -O -Wall
 
-        GHC-Prof-Options: -caf-all -rtsopts
+        GHC-Prof-Options: -rtsopts
 }
diff --git a/tests/Data/GraphViz/Testing/Properties.hs b/tests/Data/GraphViz/Testing/Properties.hs
--- a/tests/Data/GraphViz/Testing/Properties.hs
+++ b/tests/Data/GraphViz/Testing/Properties.hs
@@ -98,7 +98,7 @@
 --   should have unique 'Attributes' (namely the positions).  Note
 --   that this may not hold true with custom supplied 'Attributes'
 --   (i.e. not using one of the @dotize@ functions).
-prop_dotizeAugmentUniq   :: (DynGraph g, Eq n, Ord e) => g n e -> Bool
+prop_dotizeAugmentUniq   :: (DynGraph g, Ord e) => g n e -> Bool
 prop_dotizeAugmentUniq g = all uniqLs lss
   where
     g' = setDirectedness dotizeGraph nonClusteredParams g
@@ -137,7 +137,7 @@
 
 -- | Ensure that the definition of 'edgeInformation' for DotReprs
 --   finds all the nodes.
-prop_findAllEdges       :: (DotRepr dg Int, Ord el, Graph g) => dg Int -> g nl el -> Bool
+prop_findAllEdges       :: (DotRepr dg Int, Graph g) => dg Int -> g nl el -> Bool
 prop_findAllEdges dg' g = ((==) `on` sort) ges dges
   where
     ges = edges g
diff --git a/utils/Benchmark.hs b/utils/Benchmark.hs
--- a/utils/Benchmark.hs
+++ b/utils/Benchmark.hs
@@ -1,5 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
 {- |
    Module      : Benchmark
    Description : Benchmarking utilities for graphviz
@@ -10,13 +12,13 @@
 -}
 module Main where
 
-import Data.GraphViz hiding (DotGraph)
+import Data.GraphViz                   hiding (DotGraph)
 import Data.GraphViz.Types.Generalised
 
 import Criterion.Main
 
 import Control.DeepSeq
-import Data.Text.Lazy(Text)
+import Data.Text.Lazy  (Text)
 
 -- -----------------------------------------------------------------------------
 
