diff options
Diffstat (limited to 'psq-wrap/src/Data/Wrapper')
-rw-r--r-- | psq-wrap/src/Data/Wrapper/PSQ.hs | 91 | ||||
-rw-r--r-- | psq-wrap/src/Data/Wrapper/PSQInt.hs | 53 |
2 files changed, 144 insertions, 0 deletions
diff --git a/psq-wrap/src/Data/Wrapper/PSQ.hs b/psq-wrap/src/Data/Wrapper/PSQ.hs new file mode 100644 index 00000000..4fdeec67 --- /dev/null +++ b/psq-wrap/src/Data/Wrapper/PSQ.hs | |||
@@ -0,0 +1,91 @@ | |||
1 | {-# LANGUAGE PatternSynonyms #-} | ||
2 | {-# LANGUAGE CPP #-} | ||
3 | {-# LANGUAGE ConstraintKinds #-} | ||
4 | module Data.Wrapper.PSQ | ||
5 | #if 0 | ||
6 | ( module Data.Wrapper.PSQ , module Data.PSQueue ) where | ||
7 | |||
8 | import Data.PSQueue hiding (foldr, foldl) | ||
9 | import qualified Data.PSQueue as PSQueue | ||
10 | |||
11 | type PSQKey k = (Ord k) | ||
12 | |||
13 | -- | Wrapper over PSQueue-style foldr to implement a psqueues-style interface. | ||
14 | fold' :: (Ord k, Ord p) => (k -> p -> () -> a -> a) -> a -> PSQ k p -> a | ||
15 | fold' f a q = PSQueue.foldr f' a q | ||
16 | where | ||
17 | f' (k :-> prio) x = f k prio () x | ||
18 | |||
19 | #else | ||
20 | ( module Data.Wrapper.PSQ , module HashPSQ ) where | ||
21 | |||
22 | -- import Data.OrdPSQ as OrdPSQ hiding (insert, map, singleton, minView) | ||
23 | -- import qualified Data.OrdPSQ as OrdPSQ | ||
24 | |||
25 | import Data.Hashable | ||
26 | import qualified Data.HashPSQ as Q | ||
27 | ;import Data.HashPSQ as HashPSQ hiding (insert, map, minView, | ||
28 | singleton) | ||
29 | import Data.Time.Clock.POSIX (POSIXTime) | ||
30 | |||
31 | -- type PSQ' k p v = HashPSQ k p v | ||
32 | type PSQ' = HashPSQ | ||
33 | type PSQ k p = PSQ' k p () | ||
34 | |||
35 | type Binding' k p v = (k,p,v) | ||
36 | type Binding k p = Binding' k p () | ||
37 | |||
38 | type PSQKey k = (Hashable k, Ord k) | ||
39 | |||
40 | pattern (:->) :: k -> p -> Binding k p | ||
41 | pattern k :-> p <- (k,p,_) where k :-> p = (k,p,()) | ||
42 | |||
43 | -- I tried defining (::->) :: (k,v) -> p -> Binding' k p v | ||
44 | -- but no luck... | ||
45 | pattern Binding :: k -> v -> p -> Binding' k p v | ||
46 | pattern Binding k v p <- (k,p,v) where Binding k v p = (k,p,v) | ||
47 | |||
48 | key :: (k,p,v) -> k | ||
49 | key (k,p,v) = k | ||
50 | {-# INLINE key #-} | ||
51 | |||
52 | prio :: (k,p,v) -> p | ||
53 | prio (k,p,v) = p | ||
54 | {-# INLINE prio #-} | ||
55 | |||
56 | insert :: (PSQKey k, Ord p) => k -> p -> PSQ k p -> PSQ k p | ||
57 | insert k p q = Q.insert k p () q | ||
58 | {-# INLINE insert #-} | ||
59 | |||
60 | insert' :: (PSQKey k, Ord p) => k -> v -> p -> PSQ' k p v -> PSQ' k p v | ||
61 | insert' k v p q = Q.insert k p v q | ||
62 | {-# INLINE insert' #-} | ||
63 | |||
64 | insertWith :: (PSQKey k, Ord p) => (p -> p -> p) -> k -> p -> PSQ k p -> PSQ k p | ||
65 | insertWith f k p0 q = snd $ Q.alter f' k q | ||
66 | where | ||
67 | f' (Just (p,())) = ((),Just (f p0 p, ())) | ||
68 | f' Nothing = ((),Just (p0,())) | ||
69 | {-# INLINE insertWith #-} | ||
70 | |||
71 | singleton :: (PSQKey k, Ord p) => k -> p -> PSQ k p | ||
72 | singleton k p = Q.singleton k p () | ||
73 | {-# INLINE singleton #-} | ||
74 | |||
75 | singleton' :: (PSQKey k, Ord p) => k -> v -> p -> PSQ' k p v | ||
76 | singleton' k v p = Q.singleton k p v | ||
77 | {-# INLINE singleton' #-} | ||
78 | |||
79 | |||
80 | minView :: (PSQKey k, Ord p) => PSQ' k p v -> Maybe (Binding' k p v, PSQ' k p v) | ||
81 | minView q = fmap (\(k,p,v,q') -> (Binding k v p, q')) $ Q.minView q | ||
82 | {-# INLINE minView #-} | ||
83 | |||
84 | |||
85 | -- | Utility to convert a 'POSIXTime' delta into microseconds suitable for | ||
86 | -- passing to 'threadDelay'. | ||
87 | toMicroseconds :: POSIXTime -> Int | ||
88 | toMicroseconds = round . (* 1000) . (* 1000) | ||
89 | |||
90 | |||
91 | #endif | ||
diff --git a/psq-wrap/src/Data/Wrapper/PSQInt.hs b/psq-wrap/src/Data/Wrapper/PSQInt.hs new file mode 100644 index 00000000..5badb8b2 --- /dev/null +++ b/psq-wrap/src/Data/Wrapper/PSQInt.hs | |||
@@ -0,0 +1,53 @@ | |||
1 | {-# LANGUAGE PatternSynonyms #-} | ||
2 | {-# LANGUAGE CPP #-} | ||
3 | {-# LANGUAGE ConstraintKinds #-} | ||
4 | module Data.Wrapper.PSQInt | ||
5 | #if 0 | ||
6 | ( module Data.Wrapper.PSQInt , module Data.PSQueue ) where | ||
7 | |||
8 | import Data.PSQueue hiding (foldr, foldl, PSQ) | ||
9 | import qualified Data.PSQueue as PSQueue | ||
10 | |||
11 | type PSQ p = PSQueue.PSQ Int p | ||
12 | |||
13 | -- | Wrapper over PSQueue-style foldr to implement a psqueues-style interface. | ||
14 | fold' :: (Ord p) => (Int -> p -> () -> a -> a) -> a -> PSQ p -> a | ||
15 | fold' f a q = PSQueue.foldr f' a q | ||
16 | where | ||
17 | f' (k :-> prio) x = f k prio () x | ||
18 | |||
19 | #else | ||
20 | ( module Data.Wrapper.PSQInt | ||
21 | , module IntPSQ | ||
22 | , module Data.Wrapper.PSQ | ||
23 | ) where | ||
24 | |||
25 | import Data.Wrapper.PSQ (Binding, pattern (:->), key, prio, toMicroseconds) | ||
26 | |||
27 | import Data.IntPSQ as IntPSQ hiding (insert, map, singleton, minView) | ||
28 | import qualified Data.IntPSQ as Q | ||
29 | |||
30 | type PSQ p = IntPSQ p () | ||
31 | |||
32 | type PSQKey = () | ||
33 | |||
34 | insert :: (Ord p) => Int -> p -> PSQ p -> PSQ p | ||
35 | insert k p q = Q.insert k p () q | ||
36 | {-# INLINE insert #-} | ||
37 | |||
38 | insertWith :: (Ord p) => (p -> p -> p) -> Int -> p -> PSQ p -> PSQ p | ||
39 | insertWith f k p0 q = snd $ Q.alter f' k q | ||
40 | where | ||
41 | f' (Just (p,())) = ((),Just (f p0 p, ())) | ||
42 | f' Nothing = ((),Nothing) | ||
43 | {-# INLINE insertWith #-} | ||
44 | |||
45 | singleton :: (Ord p) => Int -> p -> PSQ p | ||
46 | singleton k p = Q.singleton k p () | ||
47 | {-# INLINE singleton #-} | ||
48 | |||
49 | minView :: (Ord p) => PSQ p -> Maybe (Binding Int p, PSQ p) | ||
50 | minView q = fmap (\(k,p,(),q') -> (k :-> p, q')) $ Q.minView q | ||
51 | {-# INLINE minView #-} | ||
52 | |||
53 | #endif | ||