iproute 1.7.4 → 1.7.5
raw patch · 4 files changed
+84/−4 lines, 4 filesdep +semigroups
Dependencies added: semigroups
Files
- Data/IP/RouteTable.hs +2/−0
- Data/IP/RouteTable/Internal.hs +42/−2
- iproute.cabal +5/−1
- test/RouteTableSpec.hs +35/−1
Data/IP/RouteTable.hs view
@@ -20,6 +20,8 @@ , I.lookupKeyValue , findMatch , fromList, toList+ , foldlWithKey+ , foldrWithKey ) where import Data.IP.RouteTable.Internal as I
Data/IP/RouteTable/Internal.hs view
@@ -20,7 +20,8 @@ import Data.IP.Range import Data.IntMap (IntMap, (!)) import qualified Data.IntMap as IM (fromList)-import Data.Monoid+import Data.Monoid hiding ((<>))+import Data.Semigroup import Data.Traversable import Data.Word import GHC.Generics (Generic, Generic1)@@ -110,12 +111,25 @@ instance Foldable (IPRTable k) where foldMap _ Nil = mempty- foldMap f (Node _ _ mv b1 b2) = foldMap f mv <> foldMap f b1 <> foldMap f b2+ foldMap f (Node _ _ mv b1 b2) = foldMap f mv `mappend` foldMap f b1 `mappend` foldMap f b2 instance Traversable (IPRTable k) where traverse _ Nil = pure Nil traverse f (Node r a mv b1 b2) = Node r a <$> traverse f mv <*> traverse f b1 <*> traverse f b2 +-- | Note that Semigroup and Monoid instances are right-biased.+-- That is, if both arguments have the same key, the value from the right+-- argument will be used.+-- Since: 1.7.5+instance Routable k => Semigroup (IPRTable k a) where+ a <> b = foldlWithKey (\rt k v -> insert k v rt) a b+ stimes = stimesIdempotent++-- | Since: 1.7.5+instance Routable k => Monoid (IPRTable k a) where+ mempty = empty+ mappend = (<>)+ ---------------------------------------------------------------- {-|@@ -301,3 +315,29 @@ foldt :: (IPRTable k a -> b -> b) -> b -> IPRTable k a -> b foldt _ v Nil = v foldt func v rt@(Node _ _ _ l r) = foldt func (foldt func (func rt v) l) r++-- | /O(n)/. Fold the keys and values in the IPRTable using the given+-- left-associative binary operator.+-- This function is equivalent to Data.Map.foldlWithKey with necessary to+-- IPRTable changes.+-- Since: 1.7.5+foldlWithKey :: (b -> AddrRange k -> a -> b) -> b -> IPRTable k a -> b+foldlWithKey f zr = go zr+ where+ go z Nil = z+ go z (Node _ _ Nothing l r) = go (go z l) r+ go z (Node n _ (Just v) l r) = go (f (go z l) n v) r+{-# INLINE foldlWithKey #-}++-- | /O(n)/. Fold the keys and values in the IPRTable using the given+-- right-associative binary operator.+-- This function is equivalent to Data.Map.foldrWithKey with necessary to+-- IPRTable changes.+-- Since: 1.7.5+foldrWithKey :: (AddrRange k -> a -> b -> b) -> b -> IPRTable k a -> b+foldrWithKey f zr = go zr+ where+ go z Nil = z+ go z (Node _ _ Nothing l r) = go (go z r) l+ go z (Node n _ (Just v) l r) = go (f n v (go z r)) l+{-# INLINE foldrWithKey #-}
iproute.cabal view
@@ -1,5 +1,5 @@ Name: iproute-Version: 1.7.4+Version: 1.7.5 Author: Kazu Yamamoto <kazu@iij.ad.jp> Maintainer: Kazu Yamamoto <kazu@iij.ad.jp> License: BSD3@@ -31,6 +31,8 @@ , byteorder , containers , network+ if impl(ghc < 8.0)+ Build-Depends: semigroups >= 0.17 Test-Suite doctest Type: exitcode-stdio-1.0@@ -57,6 +59,8 @@ , containers , network , safe+ if impl(ghc < 8.0)+ Build-Depends: semigroups >= 0.17 Source-Repository head Type: git
test/RouteTableSpec.hs view
@@ -5,12 +5,16 @@ module RouteTableSpec where #if __GLASGOW_HASKELL__ < 709-import Control.Applicative+import Control.Applicative hiding (empty) #endif import Control.Monad+import Data.Function (on) import Data.IP import Data.IP.RouteTable.Internal+import qualified Data.Foldable as Foldable import Data.List (sort, nub)+import qualified Data.List as List+import Data.Monoid ((<>)) import Test.Hspec import Test.Hspec.QuickCheck (prop) import Test.QuickCheck@@ -59,6 +63,11 @@ (fromto_ip :: [AddrRange IPv4] -> Bool) prop "expands as sorted" (fromto_ip :: [AddrRange IPv6] -> Bool)+ describe "folds" $ do+ prop "foldl" prop_foldl+ prop "foldr" prop_foldr+ describe "monoid" $ do+ prop "monoid instance" prop_monoid sort_ip :: (Routable a, Ord a) => [AddrRange a] -> Bool sort_ip xs = fromList (zip xs xs) == fromList (zip xs' xs')@@ -82,3 +91,28 @@ where ordered' _ Nil = True ordered' k1 (Node k2 _ _ _ _) = k1 >:> k2++-- Foldl and foldr properties are adapted from Data.Map tests+prop_foldl :: Int -> [(AddrRange IPv4, Int)] -> Property+prop_foldl n ys = length ys > 0 ==>+ let xs = List.nubBy ((==) `on` fst) ys+ m = fromList xs+ in Foldable.foldl (+) n m == List.foldr (+) n (List.map snd xs) &&+ Foldable.foldl (flip (:)) [] m == reverse (List.map snd (List.sort xs)) &&+ foldlWithKey (\b _ a -> a + b) n m == List.foldr (+) n (List.map snd xs)++prop_foldr :: Int -> [(AddrRange IPv4, Int)] -> Property+prop_foldr n ys = length ys > 0 ==>+ let xs = List.nubBy ((==) `on` fst) ys+ m = fromList xs+ in Foldable.foldr (+) n m == List.foldr (+) n (List.map snd xs) &&+ Foldable.foldr (:) [] m == List.map snd (List.sortBy (compare `on` fst) xs) &&+ foldrWithKey (\_ a b -> a + b) n m == List.foldr (+) n (List.map snd xs)++prop_monoid :: [(AddrRange IPv4, ())] -> [(AddrRange IPv4, ())] -> Property+prop_monoid xs ys = length xs > 0 && length ys > 0 ==>+ let xm = fromList xs+ ym = fromList ys+ in empty <> xm == xm+ && ym <> empty == ym+ && xm <> ym == fromList (xs ++ ys)