4
4
{-# LANGUAGE DeriveDataTypeable #-}
5
5
{-# LANGUAGE DeriveGeneric #-}
6
6
{-# LANGUAGE StandaloneDeriving #-}
7
+ # if __GLASGOW_HASKELL__ >= 710
8
+ {-# LANGUAGE Safe #-}
9
+ # else
7
10
{-# LANGUAGE Trustworthy #-}
11
+ # endif
8
12
#endif
9
13
10
14
#include "containers.h"
@@ -86,13 +90,14 @@ module Data.Graph (
86
90
87
91
) where
88
92
89
- #if __GLASGOW_HASKELL__
90
- # define USE_ST_MONAD 1
91
- #endif
92
-
93
93
#if USE_ST_MONAD
94
94
import Control.Monad.ST
95
- import Data.Array.ST (STUArray , newArray , readArray , writeArray )
95
+ import Data.Array.ST.Safe (newArray , readArray , writeArray )
96
+ # if USE_UNBOXED_ARRAYS
97
+ import Data.Array.ST.Safe (STUArray )
98
+ # else
99
+ import Data.Array.ST.Safe (STArray )
100
+ # endif
96
101
#else
97
102
import Data.IntSet (IntSet )
98
103
import qualified Data.IntSet as Set
@@ -110,6 +115,12 @@ import Data.Foldable as F
110
115
import Control.DeepSeq (NFData (rnf ))
111
116
import Data.Maybe
112
117
import Data.Array
118
+ #if USE_UNBOXED_ARRAYS
119
+ import qualified Data.Array.Unboxed as UA
120
+ import Data.Array.Unboxed ( UArray )
121
+ #else
122
+ import qualified Data.Array as UA
123
+ #endif
113
124
import Data.List
114
125
#if MIN_VERSION_base(4,9,0)
115
126
import Data.Functor.Classes
@@ -121,6 +132,8 @@ import Data.Data (Data)
121
132
import Data.Typeable
122
133
#endif
123
134
135
+ -- Make sure we don't use Integer by mistake.
136
+ default ()
124
137
125
138
-------------------------------------------------------------------------
126
139
-- -
@@ -269,6 +282,10 @@ type Bounds = (Vertex, Vertex)
269
282
-- | An edge from the first vertex to the second.
270
283
type Edge = (Vertex , Vertex )
271
284
285
+ #if !USE_UNBOXED_ARRAYS
286
+ type UArray i a = Array i a
287
+ #endif
288
+
272
289
-- | Returns the list of vertices in the graph.
273
290
--
274
291
-- ==== __Examples__
@@ -289,9 +306,6 @@ vertices = indices
289
306
edges :: Graph -> [Edge ]
290
307
edges g = [ (v, w) | v <- vertices g, w <- g! v ]
291
308
292
- mapT :: (Vertex -> a -> b ) -> Array Vertex a -> Array Vertex b
293
- mapT f t = array (bounds t) [ (,) v (f v (t! v)) | v <- indices t ]
294
-
295
309
-- | Build a graph from a list of edges.
296
310
--
297
311
-- Warning: This function will cause a runtime exception if a vertex in the edge
@@ -324,8 +338,11 @@ reverseE g = [ (w, v) | (v, w) <- edges g ]
324
338
--
325
339
-- > outdegree (buildG (0,2) [(0,1), (1,2)]) == array (0,2) [(0,1),(1,1),(2,0)]
326
340
outdegree :: Graph -> Array Vertex Int
327
- outdegree = mapT numEdges
328
- where numEdges _ ws = length ws
341
+ -- This is bizarrely lazy. We build an array filled with thunks, instead
342
+ -- of actually calculating anything. This is the historical behavior, and I
343
+ -- suppose someone *could* be relying on it, but it might be worth finding
344
+ -- out. Note that we *can't* be so lazy with indegree.
345
+ outdegree = fmap length
329
346
330
347
-- | A table of the count of edges into each node.
331
348
--
@@ -475,7 +492,11 @@ chop (Node v ts : us)
475
492
476
493
-- Use the ST monad if available, for constant-time primitives.
477
494
495
+ #if USE_UNBOXED_ARRAYS
478
496
newtype SetM s a = SetM { runSetM :: STUArray s Vertex Bool -> ST s a }
497
+ #else
498
+ newtype SetM s a = SetM { runSetM :: STArray s Vertex Bool -> ST s a }
499
+ #endif
479
500
480
501
instance Monad (SetM s ) where
481
502
return = pure
@@ -555,10 +576,14 @@ preorderF' ts = foldr (.) id $ map preorder' ts
555
576
preorderF :: Forest a -> [a ]
556
577
preorderF ts = preorderF' ts []
557
578
558
- tabulate :: Bounds -> [Vertex ] -> Array Vertex Int
559
- tabulate bnds vs = array bnds (zipWith (,) vs [1 .. ])
579
+ tabulate :: Bounds -> [Vertex ] -> UArray Vertex Int
580
+ tabulate bnds vs = UA. array bnds (zipWith (flip (,)) [1 .. ] vs)
581
+ -- Why zipWith (flip (,)) instead of just using zip with the
582
+ -- arguments in the other order? We want the [1..] to fuse
583
+ -- away, and these days that only happens when it's the first
584
+ -- list argument.
560
585
561
- preArr :: Bounds -> Forest Vertex -> Array Vertex Int
586
+ preArr :: Bounds -> Forest Vertex -> UArray Vertex Int
562
587
preArr bnds = tabulate bnds . preorderF
563
588
564
589
------------------------------------------------------------
@@ -622,6 +647,9 @@ cross g pre post = mapT select g
622
647
forward :: Graph -> Graph -> Table Int -> Graph
623
648
forward g tree' pre = mapT select g
624
649
where select v ws = [ w | w <- ws, pre!v < pre!w ] \\ tree' ! v
650
+
651
+ mapT :: (Vertex -> a -> b) -> Array Vertex a -> Array Vertex b
652
+ mapT f t = array (bounds t) [ (,) v (f v (t!v)) | v <- indices t ]
625
653
-}
626
654
627
655
------------------------------------------------------------
@@ -662,10 +690,10 @@ bcc g = (concat . map bicomps . map (do_label g dnum)) forest
662
690
where forest = dff g
663
691
dnum = preArr (bounds g) forest
664
692
665
- do_label :: Graph -> Array Vertex Int -> Tree Vertex -> Tree (Vertex ,Int ,Int )
666
- do_label g dnum (Node v ts) = Node (v,dnum! v, lv) us
693
+ do_label :: Graph -> UArray Vertex Int -> Tree Vertex -> Tree (Vertex ,Int ,Int )
694
+ do_label g dnum (Node v ts) = Node (v, dnum UA. ! v, lv) us
667
695
where us = map (do_label g dnum) ts
668
- lv = minimum ([dnum! v] ++ [dnum! w | w <- g! v]
696
+ lv = minimum ([dnum UA. ! v] ++ [dnum UA. ! w | w <- g! v]
669
697
++ [lu | Node (_,_,lu) _ <- us])
670
698
671
699
bicomps :: Tree (Vertex ,Int ,Int ) -> Forest [Vertex ]
0 commit comments