packages feed

fingertree 0.0.1.1 → 0.1.0.0

raw patch · 5 files changed

+384/−14 lines, 5 filesdep +HUnitdep +QuickCheckdep +test-frameworkdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: HUnit, QuickCheck, test-framework, test-framework-hunit, test-framework-quickcheck2

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.FingerTree: instance (Measured v a, Eq a) => Eq (FingerTree v a)
- Data.FingerTree: instance (Measured v a, Ord a) => Ord (FingerTree v a)
- Data.FingerTree: instance (Measured v a, Show a) => Show (FingerTree v a)
+ Data.FingerTree: instance Eq a => Eq (FingerTree v a)
+ Data.FingerTree: instance Ord a => Ord (FingerTree v a)
+ Data.FingerTree: instance Show a => Show (FingerTree v a)
+ Data.IntervalMap.FingerTree: instance Ord v => Monoid (IntervalMap v a)

Files

Data/FingerTree.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-}+{-# LANGUAGE CPP, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-} ----------------------------------------------------------------------------- -- | -- Module      :  Data.FingerTree@@ -31,7 +31,11 @@ -----------------------------------------------------------------------------  module Data.FingerTree (+#if TESTING+	FingerTree(..), Digit(..), Node(..), deep, node2, node3,+#else 	FingerTree,+#endif 	Measured(..), 	-- * Construction 	empty, singleton,@@ -54,7 +58,6 @@ import Control.Applicative (Applicative(pure, (<*>)), (<$>)) import Data.Monoid import Data.Foldable (Foldable(foldMap), toList)-import Data.Traversable (Traversable(traverse))  infixr 5 >< infixr 5 <|, :<@@ -74,13 +77,14 @@ 	deriving (Eq, Ord, Show, Read)  instance Functor s => Functor (ViewL s) where-	fmap f EmptyL           = EmptyL+	fmap _ EmptyL           = EmptyL 	fmap f (x :< xs)        = f x :< fmap f xs  instance Functor s => Functor (ViewR s) where-	fmap f EmptyR           = EmptyR+	fmap _ EmptyR           = EmptyR 	fmap f (xs :> x)        = fmap f xs :> f x +-- | 'empty' and '><'. instance Measured v a => Monoid (FingerTree v a) where 	mempty = empty 	mappend = (><)@@ -151,11 +155,15 @@ 	= Empty 	| Single a 	| Deep !v !(Digit a) (FingerTree v (Node v a)) !(Digit a)+#if TESTING+	deriving Show+#endif  deep ::  (Measured v a) =>  	 Digit a -> FingerTree v (Node v a) -> Digit a -> FingerTree v a deep pr m sf = Deep ((measure pr `mappendVal` m) `mappend` measure sf) pr m sf +-- | /O(1)/. The cached measure of a tree. instance (Measured v a) => Measured v (FingerTree v a) where 	measure Empty           =  mempty 	measure (Single x)      =  measure x@@ -167,15 +175,17 @@ 	foldMap f (Deep _ pr m sf) = 		foldMap f pr `mappend` foldMap (foldMap f) m `mappend` foldMap f sf -instance (Measured v a, Eq a) => Eq (FingerTree v a) where+instance Eq a => Eq (FingerTree v a) where 	xs == ys = toList xs == toList ys -instance (Measured v a, Ord a) => Ord (FingerTree v a) where+instance Ord a => Ord (FingerTree v a) where 	compare xs ys = compare (toList xs) (toList ys) -instance (Measured v a, Show a) => Show (FingerTree v a) where+#if !TESTING+instance Show a => Show (FingerTree v a) where 	showsPrec p xs = showParen (p > 10) $ 		showString "fromList " . shows (toList xs)+#endif  -- | Like 'fmap', but with a more constrained type. fmap' :: (Measured v1 a1, Measured v2 a2) =>@@ -350,6 +360,7 @@ consDigit a (One b) = Two a b consDigit a (Two b c) = Three a b c consDigit a (Three b c d) = Four a b c d+consDigit _ (Four _ _ _ _) = illegal_argument "consDigit"  -- | /O(1)/. Add an element to the right end of a sequence. -- Mnemonic: a triangle with the single element at the pointy end.@@ -365,6 +376,7 @@ snocDigit (One a) b = Two a b snocDigit (Two a b) c = Three a b c snocDigit (Three a b c) d = Four a b c d+snocDigit (Four _ _ _ _) _ = illegal_argument "snocDigit"  -- | /O(1)/. Is this the empty sequence? null :: (Measured v a) => FingerTree v a -> Bool@@ -390,6 +402,7 @@ lheadDigit (Four a _ _ _) = a  ltailDigit :: Digit a -> Digit a+ltailDigit (One _) = illegal_argument "ltailDigit" ltailDigit (Two _ b) = One b ltailDigit (Three _ b c) = Two b c ltailDigit (Four _ b c d) = Three b c d@@ -413,6 +426,7 @@ rheadDigit (Four _ _ _ d) = d  rtailDigit :: Digit a -> Digit a+rtailDigit (One _) = illegal_argument "rtailDigit" rtailDigit (Two a _) = One a rtailDigit (Three a b _) = Two a b rtailDigit (Four a b c _) = Three a b c@@ -672,7 +686,7 @@ -- point, i.e. that the predicate is /monotonic/. split ::  (Measured v a) =>            (v -> Bool) -> FingerTree v a -> (FingerTree v a, FingerTree v a)-split _p Empty  =  (Empty, Empty)+split _ Empty  =  (Empty, Empty) split p xs   | p (measure xs) =  (l, x <| r)   | otherwise	=  (xs, Empty)@@ -698,7 +712,8 @@  splitTree ::	(Measured v a) =>  		(v -> Bool) -> v -> FingerTree v a -> Split (FingerTree v a) a-splitTree _p _i (Single x) = Split Empty x Empty+splitTree _ _ Empty = illegal_argument "splitTree"+splitTree _ _ (Single x) = Split Empty x Empty splitTree p i (Deep _ pr m sf)   | p vpr	=  let	Split l x r	=  splitDigit p i pr 		   in	Split (maybe Empty digitToTree l) x (deepL r m sf)@@ -740,7 +755,7 @@  splitDigit :: (Measured v a) => (v -> Bool) -> v -> Digit a -> 		Split (Maybe (Digit a)) a-splitDigit p i (One a) = i `seq` Split Nothing a Nothing+splitDigit _ i (One a) = i `seq` Split Nothing a Nothing splitDigit p i (Two a b)   | p va	= Split Nothing a (Just (One b))   | otherwise	= Split (Just (One a)) b Nothing@@ -783,6 +798,10 @@ reverseDigit f (Two a b) = Two (f b) (f a) reverseDigit f (Three a b c) = Three (f c) (f b) (f a) reverseDigit f (Four a b c d) = Four (f d) (f c) (f b) (f a)++illegal_argument :: String -> a+illegal_argument name =+	error $ "Logic error: " ++ name ++ " called with illegal argument"  {- $example 
Data/IntervalMap/FingerTree.hs view
@@ -97,6 +97,11 @@ 	traverse f (IntervalMap t) = 		IntervalMap <$> FT.unsafeTraverse (traverse f) t +-- | 'empty' and 'union'.+instance (Ord v) => Monoid (IntervalMap v a) where+	mempty = empty+	mappend = union+ -- | /O(1)/.  The empty interval map. empty :: (Ord v) => IntervalMap v a empty = IntervalMap FT.empty
Data/PriorityQueue/FingerTree.hs view
@@ -136,7 +136,7 @@ null :: Ord k => PQueue k v -> Bool null (PQueue q) = FT.null q --- | /O(1)/ (/O(log(n))/ for the reduced queue).+-- | /O(1)/ for the element, /O(log(n))/ for the reduced queue. -- Returns 'Nothing' for an empty map, or the value associated with the -- minimal priority together with the rest of the priority queue. --@@ -147,7 +147,7 @@ minView :: Ord k => PQueue k v -> Maybe (v, PQueue k v) minView q = fmap (snd *** id) (minViewWithKey q) --- | /O(1)/ (/O(log(n))/ for the reduced queue).+-- | /O(1)/ for the element, /O(log(n))/ for the reduced queue. -- Returns 'Nothing' for an empty map, or the minimal (priority, value) -- pair together with the rest of the priority queue. --
fingertree.cabal view
@@ -1,6 +1,6 @@ Name:           fingertree-Version:        0.0.1.1-Cabal-Version:  >= 1.6+Version:        0.1.0.0+Cabal-Version:  >= 1.8 Copyright:      (c) 2006 Ross Paterson, Ralf Hinze License:        BSD3 License-File:   LICENSE@@ -37,3 +37,15 @@                 Data.FingerTree                 Data.IntervalMap.FingerTree                 Data.PriorityQueue.FingerTree++Test-suite ft-properties+  type: exitcode-stdio-1.0+  main-is: tests/ft-properties.hs+  cpp-options: -DTESTING+  build-depends:+                base >= 4.2 && < 6,+                HUnit,+                QuickCheck,+                test-framework,+                test-framework-hunit,+                test-framework-quickcheck2
+ tests/ft-properties.hs view
@@ -0,0 +1,334 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- QuickCheck properties for Data.FingerTree++module Main where++import Data.FingerTree    -- needs to be compiled with -DTESTING for use here++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.Framework.Providers.QuickCheck2+import Test.HUnit (Assertion, (@?=))+import Test.QuickCheck hiding ((><))+import Test.QuickCheck.Poly++import Prelude hiding (null, reverse, foldl, foldl1, foldr, foldr1, all)+import qualified Prelude++import Control.Applicative (Applicative(..))+import Control.Monad (ap)+import Data.Foldable (Foldable(..), toList, all)+import Data.Functor ((<$>))+import Data.Traversable (traverse)+import Data.List (inits)+import Data.Monoid (Monoid(..))++main :: IO ()+main = defaultMainWithOpts+    [ testProperty "foldr" prop_foldr+    , testProperty "foldl" prop_foldl+    , testProperty "(==)" prop_equals+    , testProperty "compare" prop_compare+    , testProperty "mappend" prop_mappend+    , testCase "empty" test_empty+    , testProperty "singleton" prop_singleton+    , testProperty "(<|)" prop_cons+    , testProperty "(|>)" prop_snoc+    , testProperty "(><)" prop_append+    , testProperty "fromList" prop_fromList+    , testProperty "null" prop_null+    , testProperty "viewl" prop_viewl+    , testProperty "viewr" prop_viewr+    , testProperty "split" prop_split+    , testProperty "takeUntil" prop_takeUntil+    , testProperty "dropUntil" prop_dropUntil+    , testProperty "reverse" prop_reverse+    , testProperty "fmap'" prop_fmap'+    -- , testProperty "fmapWithPos" prop_fmapWithPos -- (slow)+    , testProperty "traverse'" prop_traverse'+    -- , testProperty "traverseWithPos" prop_traverseWithPos -- (slow)+    ] runner_opts+  where+    runner_opts = mempty { ropt_test_options = Just test_opts }+    test_opts = mempty {+          topt_maximum_generated_tests = Just 500+        , topt_maximum_unsuitable_generated_tests = Just 500+        }++{--------------------------------------------------------------------+  The general plan is to compare each function with a list equivalent.+  Each operation should produce a valid tree representing the same+  sequence as produced by its list counterpart on corresponding inputs.+  (The list versions are often lazier, but these properties ignore+  strictness.)+--------------------------------------------------------------------}++-- utilities for partial conversions++infix 4 ~=++(~=) :: Eq a => Maybe a -> a -> Bool+(~=) = maybe (const False) (==)++-- Partial conversion of an output sequence to a list.+toList' :: (Eq a, Measured [a] a, Valid a) => Seq a -> Maybe [a]+toList' xs+  | valid xs = Just (toList xs)+  | otherwise = Nothing++toListPair' ::+	(Eq a, Measured [a] a, Valid a, Eq b, Measured [b] b, Valid b) =>+	(Seq a, Seq b) -> Maybe ([a], [b])+toListPair' (xs, ys) = (,) <$> toList' xs <*> toList' ys++-- instances++prop_foldr :: Seq A -> Bool+prop_foldr xs =+    foldr f z xs == Prelude.foldr f z (toList xs)+  where+    f = (:)+    z = []++prop_foldl :: Seq A -> Bool+prop_foldl xs =+    foldl f z xs == Prelude.foldl f z (toList xs)+  where+    f = flip (:)+    z = []++prop_equals :: Seq OrdA -> Seq OrdA -> Bool+prop_equals xs ys =+    (xs == ys) == (toList xs == toList ys)++prop_compare :: Seq OrdA -> Seq OrdA -> Bool+prop_compare xs ys =+    compare xs ys == compare (toList xs) (toList ys)++prop_mappend :: Seq A -> Seq A -> Bool+prop_mappend xs ys =+    toList' (mappend xs ys) ~= toList xs ++ toList ys++-- * Construction++test_empty :: Assertion+test_empty =+    toList' (empty :: Seq A) @?= Just []++prop_singleton :: A -> Bool+prop_singleton x =+    toList' (singleton x) ~= [x]++prop_cons :: A -> Seq A -> Bool+prop_cons x xs =+    toList' (x <| xs) ~= x : toList xs++prop_snoc :: Seq A -> A -> Bool+prop_snoc xs x =+    toList' (xs |> x) ~= toList xs ++ [x]++prop_append :: Seq A -> Seq A -> Bool+prop_append xs ys =+    toList' (xs >< ys) ~= toList xs ++ toList ys++prop_fromList :: [A] -> Bool+prop_fromList xs =+    toList' (fromList xs) ~= xs++-- * Deconstruction++prop_null :: Seq A -> Bool+prop_null xs =+    null xs == Prelude.null (toList xs)++prop_viewl :: Seq A -> Bool+prop_viewl xs =+    case viewl xs of+    EmptyL ->   Prelude.null (toList xs)+    x :< xs' -> valid xs' && toList xs == x : toList xs'++prop_viewr :: Seq A -> Bool+prop_viewr xs =+    case viewr xs of+    EmptyR ->   Prelude.null (toList xs)+    xs' :> x -> valid xs' && toList xs == toList xs' ++ [x]++prop_split :: Int -> Seq A -> Bool+prop_split n xs =+    toListPair' (split p xs) ~= Prelude.splitAt n (toList xs)+  where p ys = Prelude.length ys > n++prop_takeUntil :: Int -> Seq A -> Bool+prop_takeUntil n xs =+    toList' (takeUntil p xs) ~= Prelude.take n (toList xs)+  where p ys = Prelude.length ys > n++prop_dropUntil :: Int -> Seq A -> Bool+prop_dropUntil n xs =+    toList' (dropUntil p xs) ~= Prelude.drop n (toList xs)+  where p ys = Prelude.length ys > n++-- * Transformation++prop_reverse :: Seq A -> Bool+prop_reverse xs =+    toList' (reverse xs) ~= Prelude.reverse (toList xs)++prop_fmap' :: Seq A -> Bool+prop_fmap' xs =+    toList' (fmap' f xs) ~= map f (toList xs)+  where f = Just++prop_fmapWithPos :: Seq A -> Bool+prop_fmapWithPos xs =+    toList' (fmapWithPos f xs) ~= zipWith f (inits xs_list) xs_list+  where f = (,)+	xs_list = toList xs++prop_traverse' :: Seq A -> Bool+prop_traverse' xs =+    toList' (evalM (traverse' f xs)) ~= evalM (traverse f (toList xs))+  where f x = do+		n <- step+		return (n, x)++prop_traverseWithPos :: Seq A -> Bool+prop_traverseWithPos xs =+    toList' (evalM (traverseWithPos f xs)) ~= evalM (traverse (uncurry f) (zip (inits xs_list) xs_list))+  where f xs y = do+		n <- step+		return (xs, n, y)+	xs_list = toList xs++{- untested:+traverseWithPos+-}++------------------------------------------------------------------------+-- QuickCheck+------------------------------------------------------------------------++instance (Arbitrary a, Measured v a) => Arbitrary (FingerTree v a) where+	arbitrary = sized arb+	  where+		arb :: (Arbitrary a, Measured v a) => Int -> Gen (FingerTree v a)+		arb 0 = return Empty+		arb 1 = Single <$> arbitrary+		arb n = deep <$> arbitrary <*> arb (n `div` 2) <*> arbitrary++	shrink (Deep _ (One a) Empty (One b)) = [Single a, Single b]+	shrink (Deep _ pr m sf) =+		[deep pr' m sf | pr' <- shrink pr] +++		[deep pr m' sf | m' <- shrink m] +++		[deep pr m sf' | sf' <- shrink sf]+	shrink (Single x) = map Single (shrink x)+	shrink Empty = []++instance (Arbitrary a, Measured v a) => Arbitrary (Node v a) where+	arbitrary = oneof [+		node2 <$> arbitrary <*> arbitrary,+		node3 <$> arbitrary <*> arbitrary <*> arbitrary]++	shrink (Node2 _ a b) =+		[node2 a' b | a' <- shrink a] +++		[node2 a b' | b' <- shrink b]+	shrink (Node3 _ a b c) =+		[node2 a b, node2 a c, node2 b c] +++		[node3 a' b c | a' <- shrink a] +++		[node3 a b' c | b' <- shrink b] +++		[node3 a b c' | c' <- shrink c]++instance Arbitrary a => Arbitrary (Digit a) where+	arbitrary = oneof [+		One <$> arbitrary,+		Two <$> arbitrary <*> arbitrary,+		Three <$> arbitrary <*> arbitrary <*> arbitrary,+		Four <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary]++	shrink (One a) = map One (shrink a)+	shrink (Two a b) = [One a, One b]+	shrink (Three a b c) = [Two a b, Two a c, Two b c]+	shrink (Four a b c d) = [Three a b c, Three a b d, Three a c d, Three b c d]++------------------------------------------------------------------------+-- Valid trees+------------------------------------------------------------------------++class Valid a where+	valid :: a -> Bool++instance (Measured v a, Eq v, Valid a) => Valid (FingerTree v a) where+	valid Empty = True+	valid (Single x) = valid x+	valid (Deep s pr m sf) =+		s == measure pr `mappend` measure m `mappend` measure sf &&+		valid pr && valid m && valid sf++instance (Measured v a, Eq v, Valid a) => Valid (Node v a) where+	valid node = measure node == foldMap measure node && all valid node++instance Valid a => Valid (Digit a) where+	valid = all valid++instance Valid A where+	valid = const True++instance Valid (a,b) where+	valid = const True++instance Valid (a,b,c) where+	valid = const True++instance Valid (Maybe a) where+	valid = const True++instance Valid [a] where+	valid = const True++------------------------------------------------------------------------+-- Use list of elements as the measure+------------------------------------------------------------------------++type Seq a = FingerTree [a] a++instance Measured [A] A where+    measure x = [x]++instance Measured [OrdA] OrdA where+    measure x = [x]++instance Measured [Maybe a] (Maybe a) where+    measure x = [x]++instance Measured [(a, b)] (a, b) where+    measure x = [x]++instance Measured [(a, b, c)] (a, b, c) where+    measure x = [x]++------------------------------------------------------------------------+-- Simple counting monad+------------------------------------------------------------------------++newtype M a = M (Int -> (Int, a))++runM :: M a -> Int -> (Int, a)+runM (M m) = m++evalM :: M a -> a+evalM m = snd (runM m 0)++instance Monad M where+	return x = M $ \ n -> (n, x)+	M u >>= f = M $ \ m -> let (n, x) = u m in runM (f x) n++instance Functor M where+	fmap f (M u) = M $ \ m -> let (n, x) = u m in (n, f x)++instance Applicative M where+	pure = return+	(<*>) = ap++step :: M Int+step = M $ \ n -> (n+1, n)