packages feed

hw-fingertree 0.1.0.0 → 0.1.0.1

raw patch · 11 files changed

+1641/−1648 lines, 11 filesdep +hedgehogdep +hspecdep +hw-fingertreePVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependencies added: hedgehog, hspec, hw-fingertree, hw-hspec-hedgehog

API changes (from Hackage documentation)

+ HaskellWorks.Data.FingerTree: instance HaskellWorks.Data.FingerTree.Measured v a => Data.Semigroup.Semigroup (HaskellWorks.Data.FingerTree.FingerTree v a)
+ HaskellWorks.Data.IntervalMap.FingerTree: instance GHC.Classes.Ord v => Data.Semigroup.Semigroup (HaskellWorks.Data.IntervalMap.FingerTree.IntInterval v)
+ HaskellWorks.Data.IntervalMap.FingerTree: instance GHC.Classes.Ord v => Data.Semigroup.Semigroup (HaskellWorks.Data.IntervalMap.FingerTree.IntervalMap v a)
+ HaskellWorks.Data.PriorityQueue.FingerTree: instance GHC.Classes.Ord k => Data.Semigroup.Semigroup (HaskellWorks.Data.PriorityQueue.FingerTree.PQueue k v)
+ HaskellWorks.Data.PriorityQueue.FingerTree: instance GHC.Classes.Ord k => Data.Semigroup.Semigroup (HaskellWorks.Data.PriorityQueue.FingerTree.Prio k v)

Files

− HaskellWorks/Data/FingerTree.hs
@@ -1,870 +0,0 @@-{-# LANGUAGE CPP                    #-}-{-# LANGUAGE DeriveAnyClass         #-}-{-# LANGUAGE DeriveGeneric          #-}-{-# LANGUAGE FlexibleInstances      #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE MultiParamTypeClasses  #-}-{-# LANGUAGE UndecidableInstances   #-}-#if __GLASGOW_HASKELL__ >= 702-{-# LANGUAGE Safe                   #-}-#endif-#if __GLASGOW_HASKELL__ >= 710-{-# LANGUAGE AutoDeriveTypeable     #-}-#endif--------------------------------------------------------------------------------- |--- Module      :  Data.FingerTree--- Copyright   :  (c) Ross Paterson, Ralf Hinze 2006--- License     :  BSD-style--- Maintainer  :  R.Paterson@city.ac.uk--- Stability   :  experimental--- Portability :  non-portable (MPTCs and functional dependencies)------ A general sequence representation with arbitrary annotations, for--- use as a base for implementations of various collection types, as--- described in section 4 of------  * Ralf Hinze and Ross Paterson,---    \"Finger trees: a simple general-purpose data structure\",---    /Journal of Functional Programming/ 16:2 (2006) pp 197-217.---    <http://staff.city.ac.uk/~ross/papers/FingerTree.html>------ For a directly usable sequence type, see @Data.Sequence@, which is--- a specialization of this structure.------ An amortized running time is given for each operation, with /n/--- referring to the length of the sequence.  These bounds hold even in--- a persistent (shared) setting.------ /Note/: Many of these operations have the same names as similar--- operations on lists in the "Prelude".  The ambiguity may be resolved--- using either qualification or the @hiding@ clause.-----------------------------------------------------------------------------------module HaskellWorks.Data.FingerTree (-#if TESTING-    FingerTree(..), Digit(..), Node(..), deep, node2, node3,-#else-    FingerTree,-#endif-    Measured(..),-    -- * Construction-    empty, singleton,-    (<|), (|>), (><),-    fromList,-    -- * Deconstruction-    null,-    ViewL(..), ViewR(..), viewl, viewr,-    split, takeUntil, dropUntil,-    -- * Transformation-    reverse,-    fmap', fmapWithPos, unsafeFmap,-    traverse', traverseWithPos, unsafeTraverse-    -- * Example-    -- $example-    ) where--import           Prelude             hiding (null, reverse)--import           Control.Applicative (Applicative (pure, (<*>)), (<$>))-import           Control.DeepSeq-import           Data.Foldable       (Foldable (foldMap), toList)-import           Data.Monoid-import           GHC.Generics        (Generic)--infixr 5 ><-infixr 5 <|, :<-infixl 5 |>, :>---- | View of the left end of a sequence.-data ViewL s a-    = EmptyL        -- ^ empty sequence-    | a :< s a      -- ^ leftmost element and the rest of the sequence-    deriving (Eq, Ord, Show, Read, Generic, NFData)---- | View of the right end of a sequence.-data ViewR s a-    = EmptyR        -- ^ empty sequence-    | s a :> a      -- ^ the sequence minus the rightmost element,-                    -- and the rightmost element-    deriving (Eq, Ord, Show, Read, Generic, NFData)--instance Functor s => Functor (ViewL s) where-    fmap _ EmptyL    = EmptyL-    fmap f (x :< xs) = f x :< fmap f xs--instance Functor s => Functor (ViewR s) where-    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 = (><)---- Explicit Digit type (Exercise 1)--data Digit a-    = One a-    | Two a a-    | Three a a a-    | Four a a a a-    deriving (Show, Generic, NFData)--instance Foldable Digit where-    foldMap f (One a)        = f a-    foldMap f (Two a b)      = f a `mappend` f b-    foldMap f (Three a b c)  = f a `mappend` f b `mappend` f c-    foldMap f (Four a b c d) = f a `mappend` f b `mappend` f c `mappend` f d------------------------ 4.1 Measurements------------------------ | Things that can be measured.-class (Monoid v) => Measured v a | a -> v where-    measure :: a -> v--instance (Measured v a) => Measured v (Digit a) where-    measure = foldMap measure-------------------------------- 4.2 Caching measurements------------------------------data Node v a = Node2 !v a a | Node3 !v a a a-    deriving (Show, Generic, NFData)--instance Foldable (Node v) where-    foldMap f (Node2 _ a b)   = f a `mappend` f b-    foldMap f (Node3 _ a b c) = f a `mappend` f b `mappend` f c--node2        ::  (Measured v a) => a -> a -> Node v a-node2 a b    =   Node2 (measure a `mappend` measure b) a b--node3        ::  (Measured v a) => a -> a -> a -> Node v a-node3 a b c  =   Node3 (measure a `mappend` measure b `mappend` measure c) a b c--instance (Monoid v) => Measured v (Node v a) where-    measure (Node2 v _ _)   =  v-    measure (Node3 v _ _ _) =  v--nodeToDigit :: Node v a -> Digit a-nodeToDigit (Node2 _ a b)   = Two a b-nodeToDigit (Node3 _ a b c) = Three a b c---- | A representation of a sequence of values of type @a@, allowing--- access to the ends in constant time, and append and split in time--- logarithmic in the size of the smaller piece.------ The collection is also parameterized by a measure type @v@, which--- is used to specify a position in the sequence for the 'split' operation.--- The types of the operations enforce the constraint @'Measured' v a@,--- which also implies that the type @v@ is determined by @a@.------ A variety of abstract data types can be implemented by using different--- element types and measurements.-data FingerTree v a-    = Empty-    | Single a-    | Deep !v !(Digit a) (FingerTree v (Node v a)) !(Digit a)-    deriving (-#if TESTING-    Show,-#endif-    Generic, NFData)--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-    measure (Deep v _ _ _) =  v--instance Foldable (FingerTree v) where-    foldMap _ Empty = mempty-    foldMap f (Single x) = f x-    foldMap f (Deep _ pr m sf) =-        foldMap f pr `mappend` foldMap (foldMap f) m `mappend` foldMap f sf--instance Eq a => Eq (FingerTree v a) where-    xs == ys = toList xs == toList ys--instance Ord a => Ord (FingerTree v a) where-    compare xs ys = compare (toList xs) (toList ys)--#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) =>-    (a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2-fmap' = mapTree--mapTree :: (Measured v2 a2) =>-    (a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2-mapTree _ Empty = Empty-mapTree f (Single x) = Single (f x)-mapTree f (Deep _ pr m sf) =-    deep (mapDigit f pr) (mapTree (mapNode f) m) (mapDigit f sf)--mapNode :: (Measured v2 a2) =>-    (a1 -> a2) -> Node v1 a1 -> Node v2 a2-mapNode f (Node2 _ a b)   = node2 (f a) (f b)-mapNode f (Node3 _ a b c) = node3 (f a) (f b) (f c)--mapDigit :: (a -> b) -> Digit a -> Digit b-mapDigit f (One a)        = One (f a)-mapDigit f (Two a b)      = Two (f a) (f b)-mapDigit f (Three a b c)  = Three (f a) (f b) (f c)-mapDigit f (Four a b c d) = Four (f a) (f b) (f c) (f d)---- | Map all elements of the tree with a function that also takes the--- measure of the prefix of the tree to the left of the element.-fmapWithPos :: (Measured v1 a1, Measured v2 a2) =>-    (v1 -> a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2-fmapWithPos f = mapWPTree f mempty--mapWPTree :: (Measured v1 a1, Measured v2 a2) =>-    (v1 -> a1 -> a2) -> v1 -> FingerTree v1 a1 -> FingerTree v2 a2-mapWPTree _ _ Empty = Empty-mapWPTree f v (Single x) = Single (f v x)-mapWPTree f v (Deep _ pr m sf) =-    deep (mapWPDigit f v pr)-         (mapWPTree (mapWPNode f) vpr m)-         (mapWPDigit f vm sf)-  where-    vpr     =  v    `mappend`  measure pr-    vm      =  vpr  `mappendVal` m--mapWPNode :: (Measured v1 a1, Measured v2 a2) =>-    (v1 -> a1 -> a2) -> v1 -> Node v1 a1 -> Node v2 a2-mapWPNode f v (Node2 _ a b) = node2 (f v a) (f va b)-  where-    va      = v `mappend` measure a-mapWPNode f v (Node3 _ a b c) = node3 (f v a) (f va b) (f vab c)-  where-    va      = v `mappend` measure a-    vab     = va `mappend` measure b--mapWPDigit :: (Measured v a) => (v -> a -> b) -> v -> Digit a -> Digit b-mapWPDigit f v (One a) = One (f v a)-mapWPDigit f v (Two a b) = Two (f v a) (f va b)-  where-    va      = v `mappend` measure a-mapWPDigit f v (Three a b c) = Three (f v a) (f va b) (f vab c)-  where-    va      = v `mappend` measure a-    vab     = va `mappend` measure b-mapWPDigit f v (Four a b c d) = Four (f v a) (f va b) (f vab c) (f vabc d)-  where-    va      = v `mappend` measure a-    vab     = va `mappend` measure b-    vabc    = vab `mappend` measure c---- | Like 'fmap', but safe only if the function preserves the measure.-unsafeFmap :: (a -> b) -> FingerTree v a -> FingerTree v b-unsafeFmap _ Empty = Empty-unsafeFmap f (Single x) = Single (f x)-unsafeFmap f (Deep v pr m sf) =-    Deep v (mapDigit f pr) (unsafeFmap (unsafeFmapNode f) m) (mapDigit f sf)--unsafeFmapNode :: (a -> b) -> Node v a -> Node v b-unsafeFmapNode f (Node2 v a b)   = Node2 v (f a) (f b)-unsafeFmapNode f (Node3 v a b c) = Node3 v (f a) (f b) (f c)---- | Like 'traverse', but with a more constrained type.-traverse' :: (Measured v1 a1, Measured v2 a2, Applicative f) =>-    (a1 -> f a2) -> FingerTree v1 a1 -> f (FingerTree v2 a2)-traverse' = traverseTree--traverseTree :: (Measured v2 a2, Applicative f) =>-    (a1 -> f a2) -> FingerTree v1 a1 -> f (FingerTree v2 a2)-traverseTree _ Empty = pure Empty-traverseTree f (Single x) = Single <$> f x-traverseTree f (Deep _ pr m sf) =-    deep <$> traverseDigit f pr <*> traverseTree (traverseNode f) m <*> traverseDigit f sf--traverseNode :: (Measured v2 a2, Applicative f) =>-    (a1 -> f a2) -> Node v1 a1 -> f (Node v2 a2)-traverseNode f (Node2 _ a b)   = node2 <$> f a <*> f b-traverseNode f (Node3 _ a b c) = node3 <$> f a <*> f b <*> f c--traverseDigit :: (Applicative f) => (a -> f b) -> Digit a -> f (Digit b)-traverseDigit f (One a)        = One <$> f a-traverseDigit f (Two a b)      = Two <$> f a <*> f b-traverseDigit f (Three a b c)  = Three <$> f a <*> f b <*> f c-traverseDigit f (Four a b c d) = Four <$> f a <*> f b <*> f c <*> f d---- | Traverse the tree with a function that also takes the--- measure of the prefix of the tree to the left of the element.-traverseWithPos :: (Measured v1 a1, Measured v2 a2, Applicative f) =>-    (v1 -> a1 -> f a2) -> FingerTree v1 a1 -> f (FingerTree v2 a2)-traverseWithPos f = traverseWPTree f mempty--traverseWPTree :: (Measured v1 a1, Measured v2 a2, Applicative f) =>-    (v1 -> a1 -> f a2) -> v1 -> FingerTree v1 a1 -> f (FingerTree v2 a2)-traverseWPTree _ _ Empty = pure Empty-traverseWPTree f v (Single x) = Single <$> f v x-traverseWPTree f v (Deep _ pr m sf) =-    deep <$> traverseWPDigit f v pr <*> traverseWPTree (traverseWPNode f) vpr m <*> traverseWPDigit f vm sf-  where-    vpr     =  v    `mappend`  measure pr-    vm      =  vpr  `mappendVal` m--traverseWPNode :: (Measured v1 a1, Measured v2 a2, Applicative f) =>-    (v1 -> a1 -> f a2) -> v1 -> Node v1 a1 -> f (Node v2 a2)-traverseWPNode f v (Node2 _ a b) = node2 <$> f v a <*> f va b-  where-    va      = v `mappend` measure a-traverseWPNode f v (Node3 _ a b c) = node3 <$> f v a <*> f va b <*> f vab c-  where-    va      = v `mappend` measure a-    vab     = va `mappend` measure b--traverseWPDigit :: (Measured v a, Applicative f) =>-    (v -> a -> f b) -> v -> Digit a -> f (Digit b)-traverseWPDigit f v (One a) = One <$> f v a-traverseWPDigit f v (Two a b) = Two <$> f v a <*> f va b-  where-    va      = v `mappend` measure a-traverseWPDigit f v (Three a b c) = Three <$> f v a <*> f va b <*> f vab c-  where-    va      = v `mappend` measure a-    vab     = va `mappend` measure b-traverseWPDigit f v (Four a b c d) = Four <$> f v a <*> f va b <*> f vab c <*> f vabc d-  where-    va      = v `mappend` measure a-    vab     = va `mappend` measure b-    vabc    = vab `mappend` measure c---- | Like 'traverse', but safe only if the function preserves the measure.-unsafeTraverse :: (Applicative f) =>-    (a -> f b) -> FingerTree v a -> f (FingerTree v b)-unsafeTraverse _ Empty = pure Empty-unsafeTraverse f (Single x) = Single <$> f x-unsafeTraverse f (Deep v pr m sf) =-    Deep v <$> traverseDigit f pr <*> unsafeTraverse (unsafeTraverseNode f) m <*> traverseDigit f sf--unsafeTraverseNode :: (Applicative f) =>-    (a -> f b) -> Node v a -> f (Node v b)-unsafeTraverseNode f (Node2 v a b)   = Node2 v <$> f a <*> f b-unsafeTraverseNode f (Node3 v a b c) = Node3 v <$> f a <*> f b <*> f c---------------------------------------------------------- 4.3 Construction, deconstruction and concatenation---------------------------------------------------------- | /O(1)/. The empty sequence.-empty :: Measured v a => FingerTree v a-empty = Empty---- | /O(1)/. A singleton sequence.-singleton :: Measured v a => a -> FingerTree v a-singleton = Single---- | /O(n)/. Create a sequence from a finite list of elements.-fromList :: (Measured v a) => [a] -> FingerTree v a-fromList = foldr (<|) Empty---- | /O(1)/. Add an element to the left end of a sequence.--- Mnemonic: a triangle with the single element at the pointy end.-(<|) :: (Measured v a) => a -> FingerTree v a -> FingerTree v a-a <| Empty              =  Single a-a <| Single b           =  deep (One a) Empty (One b)-a <| Deep v (Four b c d e) m sf = m `seq`-    Deep (measure a `mappend` v) (Two a b) (node3 c d e <| m) sf-a <| Deep v pr m sf     =-    Deep (measure a `mappend` v) (consDigit a pr) m sf--consDigit :: a -> Digit a -> Digit a-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.-(|>) :: (Measured v a) => FingerTree v a -> a -> FingerTree v a-Empty |> a              =  Single a-Single a |> b           =  deep (One a) Empty (One b)-Deep v pr m (Four a b c d) |> e = m `seq`-    Deep (v `mappend` measure e) pr (m |> node3 a b c) (Two d e)-Deep v pr m sf |> x     =-    Deep (v `mappend` measure x) pr m (snocDigit sf x)--snocDigit :: Digit a -> a -> Digit a-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-null Empty = True-null _     = False---- | /O(1)/. Analyse the left end of a sequence.-viewl :: (Measured v a) => FingerTree v a -> ViewL (FingerTree v) a-viewl Empty                 =  EmptyL-viewl (Single x)            =  x :< Empty-viewl (Deep _ (One x) m sf) =  x :< rotL m sf-viewl (Deep _ pr m sf)      =  lheadDigit pr :< deep (ltailDigit pr) m sf--rotL :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> FingerTree v a-rotL m sf      =   case viewl m of-    EmptyL  ->  digitToTree sf-    a :< m' ->  Deep (measure m `mappend` measure sf) (nodeToDigit a) m' sf--lheadDigit :: Digit a -> a-lheadDigit (One a)        = a-lheadDigit (Two a _)      = a-lheadDigit (Three a _ _)  = a-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---- | /O(1)/. Analyse the right end of a sequence.-viewr :: (Measured v a) => FingerTree v a -> ViewR (FingerTree v) a-viewr Empty                 =  EmptyR-viewr (Single x)            =  Empty :> x-viewr (Deep _ pr m (One x)) =  rotR pr m :> x-viewr (Deep _ pr m sf)      =  deep pr m (rtailDigit sf) :> rheadDigit sf--rotR :: (Measured v a) => Digit a -> FingerTree v (Node v a) -> FingerTree v a-rotR pr m = case viewr m of-    EmptyR  ->  digitToTree pr-    m' :> a ->  Deep (measure pr `mappendVal` m) pr m' (nodeToDigit a)--rheadDigit :: Digit a -> a-rheadDigit (One a)        = a-rheadDigit (Two _ b)      = b-rheadDigit (Three _ _ c)  = c-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--digitToTree :: (Measured v a) => Digit a -> FingerTree v a-digitToTree (One a)        = Single a-digitToTree (Two a b)      = deep (One a) Empty (One b)-digitToTree (Three a b c)  = deep (Two a b) Empty (One c)-digitToTree (Four a b c d) = deep (Two a b) Empty (Two c d)--------------------- Concatenation--------------------- | /O(log(min(n1,n2)))/. Concatenate two sequences.-(><) :: (Measured v a) => FingerTree v a -> FingerTree v a -> FingerTree v a-(><) =  appendTree0--appendTree0 :: (Measured v a) => FingerTree v a -> FingerTree v a -> FingerTree v a-appendTree0 Empty xs =-    xs-appendTree0 xs Empty =-    xs-appendTree0 (Single x) xs =-    x <| xs-appendTree0 xs (Single x) =-    xs |> x-appendTree0 (Deep _ pr1 m1 sf1) (Deep _ pr2 m2 sf2) =-    deep pr1 (addDigits0 m1 sf1 pr2 m2) sf2--addDigits0 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)-addDigits0 m1 (One a) (One b) m2 =-    appendTree1 m1 (node2 a b) m2-addDigits0 m1 (One a) (Two b c) m2 =-    appendTree1 m1 (node3 a b c) m2-addDigits0 m1 (One a) (Three b c d) m2 =-    appendTree2 m1 (node2 a b) (node2 c d) m2-addDigits0 m1 (One a) (Four b c d e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits0 m1 (Two a b) (One c) m2 =-    appendTree1 m1 (node3 a b c) m2-addDigits0 m1 (Two a b) (Two c d) m2 =-    appendTree2 m1 (node2 a b) (node2 c d) m2-addDigits0 m1 (Two a b) (Three c d e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits0 m1 (Two a b) (Four c d e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits0 m1 (Three a b c) (One d) m2 =-    appendTree2 m1 (node2 a b) (node2 c d) m2-addDigits0 m1 (Three a b c) (Two d e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits0 m1 (Three a b c) (Three d e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits0 m1 (Three a b c) (Four d e f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits0 m1 (Four a b c d) (One e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits0 m1 (Four a b c d) (Two e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits0 m1 (Four a b c d) (Three e f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits0 m1 (Four a b c d) (Four e f g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2--appendTree1 :: (Measured v a) => FingerTree v a -> a -> FingerTree v a -> FingerTree v a-appendTree1 Empty a xs =-    a <| xs-appendTree1 xs a Empty =-    xs |> a-appendTree1 (Single x) a xs =-    x <| a <| xs-appendTree1 xs a (Single x) =-    xs |> a |> x-appendTree1 (Deep _ pr1 m1 sf1) a (Deep _ pr2 m2 sf2) =-    deep pr1 (addDigits1 m1 sf1 a pr2 m2) sf2--addDigits1 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)-addDigits1 m1 (One a) b (One c) m2 =-    appendTree1 m1 (node3 a b c) m2-addDigits1 m1 (One a) b (Two c d) m2 =-    appendTree2 m1 (node2 a b) (node2 c d) m2-addDigits1 m1 (One a) b (Three c d e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits1 m1 (One a) b (Four c d e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits1 m1 (Two a b) c (One d) m2 =-    appendTree2 m1 (node2 a b) (node2 c d) m2-addDigits1 m1 (Two a b) c (Two d e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits1 m1 (Two a b) c (Three d e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits1 m1 (Two a b) c (Four d e f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits1 m1 (Three a b c) d (One e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits1 m1 (Three a b c) d (Two e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits1 m1 (Three a b c) d (Three e f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits1 m1 (Three a b c) d (Four e f g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits1 m1 (Four a b c d) e (One f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits1 m1 (Four a b c d) e (Two f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits1 m1 (Four a b c d) e (Three f g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits1 m1 (Four a b c d) e (Four f g h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2--appendTree2 :: (Measured v a) => FingerTree v a -> a -> a -> FingerTree v a -> FingerTree v a-appendTree2 Empty a b xs =-    a <| b <| xs-appendTree2 xs a b Empty =-    xs |> a |> b-appendTree2 (Single x) a b xs =-    x <| a <| b <| xs-appendTree2 xs a b (Single x) =-    xs |> a |> b |> x-appendTree2 (Deep _ pr1 m1 sf1) a b (Deep _ pr2 m2 sf2) =-    deep pr1 (addDigits2 m1 sf1 a b pr2 m2) sf2--addDigits2 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> a -> a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)-addDigits2 m1 (One a) b c (One d) m2 =-    appendTree2 m1 (node2 a b) (node2 c d) m2-addDigits2 m1 (One a) b c (Two d e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits2 m1 (One a) b c (Three d e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits2 m1 (One a) b c (Four d e f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits2 m1 (Two a b) c d (One e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits2 m1 (Two a b) c d (Two e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits2 m1 (Two a b) c d (Three e f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits2 m1 (Two a b) c d (Four e f g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits2 m1 (Three a b c) d e (One f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits2 m1 (Three a b c) d e (Two f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits2 m1 (Three a b c) d e (Three f g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits2 m1 (Three a b c) d e (Four f g h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits2 m1 (Four a b c d) e f (One g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits2 m1 (Four a b c d) e f (Two g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits2 m1 (Four a b c d) e f (Three g h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits2 m1 (Four a b c d) e f (Four g h i j) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2--appendTree3 :: (Measured v a) => FingerTree v a -> a -> a -> a -> FingerTree v a -> FingerTree v a-appendTree3 Empty a b c xs =-    a <| b <| c <| xs-appendTree3 xs a b c Empty =-    xs |> a |> b |> c-appendTree3 (Single x) a b c xs =-    x <| a <| b <| c <| xs-appendTree3 xs a b c (Single x) =-    xs |> a |> b |> c |> x-appendTree3 (Deep _ pr1 m1 sf1) a b c (Deep _ pr2 m2 sf2) =-    deep pr1 (addDigits3 m1 sf1 a b c pr2 m2) sf2--addDigits3 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> a -> a -> a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)-addDigits3 m1 (One a) b c d (One e) m2 =-    appendTree2 m1 (node3 a b c) (node2 d e) m2-addDigits3 m1 (One a) b c d (Two e f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits3 m1 (One a) b c d (Three e f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits3 m1 (One a) b c d (Four e f g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits3 m1 (Two a b) c d e (One f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits3 m1 (Two a b) c d e (Two f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits3 m1 (Two a b) c d e (Three f g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits3 m1 (Two a b) c d e (Four f g h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits3 m1 (Three a b c) d e f (One g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits3 m1 (Three a b c) d e f (Two g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits3 m1 (Three a b c) d e f (Three g h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits3 m1 (Three a b c) d e f (Four g h i j) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2-addDigits3 m1 (Four a b c d) e f g (One h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits3 m1 (Four a b c d) e f g (Two h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits3 m1 (Four a b c d) e f g (Three h i j) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2-addDigits3 m1 (Four a b c d) e f g (Four h i j k) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node3 g h i) (node2 j k) m2--appendTree4 :: (Measured v a) => FingerTree v a -> a -> a -> a -> a -> FingerTree v a -> FingerTree v a-appendTree4 Empty a b c d xs =-    a <| b <| c <| d <| xs-appendTree4 xs a b c d Empty =-    xs |> a |> b |> c |> d-appendTree4 (Single x) a b c d xs =-    x <| a <| b <| c <| d <| xs-appendTree4 xs a b c d (Single x) =-    xs |> a |> b |> c |> d |> x-appendTree4 (Deep _ pr1 m1 sf1) a b c d (Deep _ pr2 m2 sf2) =-    deep pr1 (addDigits4 m1 sf1 a b c d pr2 m2) sf2--addDigits4 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> a -> a -> a -> a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)-addDigits4 m1 (One a) b c d e (One f) m2 =-    appendTree2 m1 (node3 a b c) (node3 d e f) m2-addDigits4 m1 (One a) b c d e (Two f g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits4 m1 (One a) b c d e (Three f g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits4 m1 (One a) b c d e (Four f g h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits4 m1 (Two a b) c d e f (One g) m2 =-    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2-addDigits4 m1 (Two a b) c d e f (Two g h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits4 m1 (Two a b) c d e f (Three g h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits4 m1 (Two a b) c d e f (Four g h i j) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2-addDigits4 m1 (Three a b c) d e f g (One h) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2-addDigits4 m1 (Three a b c) d e f g (Two h i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits4 m1 (Three a b c) d e f g (Three h i j) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2-addDigits4 m1 (Three a b c) d e f g (Four h i j k) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node3 g h i) (node2 j k) m2-addDigits4 m1 (Four a b c d) e f g h (One i) m2 =-    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2-addDigits4 m1 (Four a b c d) e f g h (Two i j) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2-addDigits4 m1 (Four a b c d) e f g h (Three i j k) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node3 g h i) (node2 j k) m2-addDigits4 m1 (Four a b c d) e f g h (Four i j k l) m2 =-    appendTree4 m1 (node3 a b c) (node3 d e f) (node3 g h i) (node3 j k l) m2--------------------- 4.4 Splitting--------------------- | /O(log(min(i,n-i)))/. Split a sequence at a point where the predicate--- on the accumulated measure changes from 'False' to 'True'.------ For predictable results, one should ensure that there is only one such--- point, i.e. that the predicate is /monotonic/.-split ::  (Measured v a) =>-      (v -> Bool) -> FingerTree v a -> (FingerTree v a, FingerTree v a)-split _ Empty  =  (Empty, Empty)-split p xs-  | p (measure xs) =  (l, x <| r)-  | otherwise   =  (xs, Empty)-  where-    Split l x r = splitTree p mempty xs---- | /O(log(min(i,n-i)))/.--- Given a monotonic predicate @p@, @'takeUntil' p t@ is the largest--- prefix of @t@ whose measure does not satisfy @p@.------ *  @'takeUntil' p t = 'fst' ('split' p t)@-takeUntil :: (Measured v a) => (v -> Bool) -> FingerTree v a -> FingerTree v a-takeUntil p  =  fst . split p---- | /O(log(min(i,n-i)))/.--- Given a monotonic predicate @p@, @'dropUntil' p t@ is the rest of @t@--- after removing the largest prefix whose measure does not satisfy @p@.------ * @'dropUntil' p t = 'snd' ('split' p t)@-dropUntil :: (Measured v a) => (v -> Bool) -> FingerTree v a -> FingerTree v a-dropUntil p  =  snd . split p--data Split t a = Split t a t--splitTree :: (Measured v a) =>-    (v -> Bool) -> v -> FingerTree v a -> Split (FingerTree v a) a-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)-  | p vm        =  let  Split ml xs mr  =  splitTree p vpr m-                        Split l x r     =  splitNode p (vpr `mappendVal` ml) xs-                   in   Split (deepR pr  ml l) x (deepL r mr sf)-  | otherwise   =  let  Split l x r     =  splitDigit p vm sf-                   in   Split (deepR pr  m  l) x (maybe Empty digitToTree r)-  where-    vpr     =  i    `mappend`  measure pr-    vm      =  vpr  `mappendVal` m---- Avoid relying on right identity (cf Exercise 7)-mappendVal :: (Measured v a) => v -> FingerTree v a -> v-mappendVal v Empty = v-mappendVal v t     = v `mappend` measure t--deepL :: (Measured v a) =>-    Maybe (Digit a) -> FingerTree v (Node v a) -> Digit a -> FingerTree v a-deepL Nothing m sf   =   rotL m sf-deepL (Just pr) m sf =   deep pr m sf--deepR :: (Measured v a) =>-    Digit a -> FingerTree v (Node v a) -> Maybe (Digit a) -> FingerTree v a-deepR pr m Nothing   =   rotR pr m-deepR pr m (Just sf) =   deep pr m sf--splitNode :: (Measured v a) => (v -> Bool) -> v -> Node v a ->-    Split (Maybe (Digit a)) a-splitNode p i (Node2 _ a b)-  | p va        = Split Nothing a (Just (One b))-  | otherwise   = Split (Just (One a)) b Nothing-  where-    va      = i `mappend` measure a-splitNode p i (Node3 _ a b c)-  | p va        = Split Nothing a (Just (Two b c))-  | p vab       = Split (Just (One a)) b (Just (One c))-  | otherwise   = Split (Just (Two a b)) c Nothing-  where-    va      = i `mappend` measure a-    vab     = va `mappend` measure b--splitDigit :: (Measured v a) => (v -> Bool) -> v -> Digit a ->-    Split (Maybe (Digit a)) a-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-  where-    va      = i `mappend` measure a-splitDigit p i (Three a b c)-  | p va        = Split Nothing a (Just (Two b c))-  | p vab       = Split (Just (One a)) b (Just (One c))-  | otherwise   = Split (Just (Two a b)) c Nothing-  where-    va      = i `mappend` measure a-    vab     = va `mappend` measure b-splitDigit p i (Four a b c d)-  | p va        = Split Nothing a (Just (Three b c d))-  | p vab       = Split (Just (One a)) b (Just (Two c d))-  | p vabc      = Split (Just (Two a b)) c (Just (One d))-  | otherwise   = Split (Just (Three a b c)) d Nothing-  where-    va      = i `mappend` measure a-    vab     = va `mappend` measure b-    vabc    = vab `mappend` measure c----------------------- Transformations----------------------- | /O(n)/. The reverse of a sequence.-reverse :: (Measured v a) => FingerTree v a -> FingerTree v a-reverse = reverseTree id--reverseTree :: (Measured v2 a2) => (a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2-reverseTree _ Empty = Empty-reverseTree f (Single x) = Single (f x)-reverseTree f (Deep _ pr m sf) =-    deep (reverseDigit f sf) (reverseTree (reverseNode f) m) (reverseDigit f pr)--reverseNode :: (Measured v2 a2) => (a1 -> a2) -> Node v1 a1 -> Node v2 a2-reverseNode f (Node2 _ a b)   = node2 (f b) (f a)-reverseNode f (Node3 _ a b c) = node3 (f c) (f b) (f a)--reverseDigit :: (a -> b) -> Digit a -> Digit b-reverseDigit f (One a)        = One (f a)-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--Particular abstract data types may be implemented by defining-element types with suitable 'Measured' instances.--(from section 4.5 of the paper)-Simple sequences can be implemented using a 'Sum' monoid as a measure:--> newtype Elem a = Elem { getElem :: a }->-> instance Measured (Sum Int) (Elem a) where->     measure (Elem _) = Sum 1->-> newtype Seq a = Seq (FingerTree (Sum Int) (Elem a))--Then the measure of a subsequence is simply its length.-This representation supports log-time extraction of subsequences:--> take :: Int -> Seq a -> Seq a-> take k (Seq xs) = Seq (takeUntil (> Sum k) xs)->-> drop :: Int -> Seq a -> Seq a-> drop k (Seq xs) = Seq (dropUntil (> Sum k) xs)--The module @Data.Sequence@ is an optimized instantiation of this type.--For further examples, see "Data.IntervalMap.FingerTree" and-"Data.PriorityQueue.FingerTree".---}
− HaskellWorks/Data/IntervalMap/FingerTree.hs
@@ -1,220 +0,0 @@-{-# LANGUAGE CPP                   #-}-{-# LANGUAGE DeriveAnyClass        #-}-{-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE MultiParamTypeClasses #-}-#if __GLASGOW_HASKELL__ >= 702-{-# LANGUAGE Safe                  #-}-#endif-#if __GLASGOW_HASKELL__ >= 710-{-# LANGUAGE AutoDeriveTypeable    #-}-#endif--------------------------------------------------------------------------------- |--- Module      :  Data.PriorityQueue.FingerTree--- Copyright   :  (c) Ross Paterson 2008--- License     :  BSD-style--- Maintainer  :  R.Paterson@city.ac.uk--- Stability   :  experimental--- Portability :  non-portable (MPTCs and functional dependencies)------ Interval maps implemented using the 'FingerTree' type, following--- section 4.8 of------  * Ralf Hinze and Ross Paterson,---    \"Finger trees: a simple general-purpose data structure\",---    /Journal of Functional Programming/ 16:2 (2006) pp 197-217.---    <http://staff.city.ac.uk/~ross/papers/FingerTree.html>------ An amortized running time is given for each operation, with /n/--- referring to the size of the priority queue.  These bounds hold even--- in a persistent (shared) setting.------ /Note/: Many of these operations have the same names as similar--- operations on lists in the "Prelude".  The ambiguity may be resolved--- using either qualification or the @hiding@ clause.-----------------------------------------------------------------------------------module HaskellWorks.Data.IntervalMap.FingerTree (-    -- * Intervals-    Interval(..), point,-    -- * Interval maps-    IntervalMap(..), empty, singleton, insert, union,-    -- * Searching-    search, intersections, dominators-    ) where--import           HaskellWorks.Data.FingerTree (FingerTree, Measured (..),-                                               ViewL (..), (<|), (><))-import qualified HaskellWorks.Data.FingerTree as FT--import           Control.Applicative          ((<$>))-import           Control.DeepSeq-import           Data.Foldable                (Foldable (foldMap))-import           Data.Monoid-import           Data.Traversable             (Traversable (traverse))-import           GHC.Generics--------------------------------------- 4.8 Application: interval trees--------------------------------------- | A closed interval.  The lower bound should be less than or equal--- to the higher bound.-data Interval v = Interval { low :: v, high :: v }-    deriving (Eq, Ord, Show, Generic, NFData)---- | An interval in which the lower and upper bounds are equal.-point :: v -> Interval v-point v = Interval v v--data Node v a = Node (Interval v) a deriving (Generic, NFData)--instance Functor (Node v) where-    fmap f (Node i x) = Node i (f x)--instance Foldable (Node v) where-    foldMap f (Node _ x) = f x--instance Traversable (Node v) where-    traverse f (Node i x) = Node i <$> f x---- rightmost interval (including largest lower bound) and largest upper bound.-data IntInterval v = NoInterval | IntInterval (Interval v) v deriving (Generic, NFData)--instance Ord v => Monoid (IntInterval v) where-    mempty = NoInterval-    NoInterval `mappend` i  = i-    i `mappend` NoInterval  = i-    IntInterval _ hi1 `mappend` IntInterval int2 hi2 =-        IntInterval int2 (max hi1 hi2)--instance (Ord v) => Measured (IntInterval v) (Node v a) where-    measure (Node i _) = IntInterval i (high i)---- | Map of closed intervals, possibly with duplicates.--- The 'Foldable' and 'Traversable' instances process the intervals in--- lexicographical order.-newtype IntervalMap v a =-    IntervalMap (FingerTree (IntInterval v) (Node v a))-    deriving (Generic, NFData)--- ordered lexicographically by interval--instance Functor (IntervalMap v) where-    fmap f (IntervalMap t) = IntervalMap (FT.unsafeFmap (fmap f) t)--instance Foldable (IntervalMap v) where-    foldMap f (IntervalMap t) = foldMap (foldMap f) t--instance Traversable (IntervalMap v) where-    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---- | /O(1)/.  Interval map with a single entry.-singleton :: (Ord v) => Interval v -> a -> IntervalMap v a-singleton i x = IntervalMap (FT.singleton (Node i x))---- | /O(log n)/.  Insert an interval into a map.--- The map may contain duplicate intervals; the new entry will be inserted--- before any existing entries for the same interval.-insert :: (Ord v) => Interval v -> a -> IntervalMap v a -> IntervalMap v a-insert (Interval lo hi) _ m | lo > hi = m-insert i x (IntervalMap t) = IntervalMap (l >< Node i x <| r)-  where-    (l, r) = FT.split larger t-    larger (IntInterval k _) = k >= i-    larger NoInterval        = error "larger NoInterval"---- | /O(m log (n/\//m))/.  Merge two interval maps.--- The map may contain duplicate intervals; entries with equal intervals--- are kept in the original order.-union  ::  (Ord v) => IntervalMap v a -> IntervalMap v a -> IntervalMap v a-union (IntervalMap xs) (IntervalMap ys) = IntervalMap (merge1 xs ys)-  where-    merge1 as bs = case FT.viewl as of-        EmptyL                  -> bs-        a@(Node i _) :< as'     -> l >< a <| merge2 as' r-          where-            (l, r) = FT.split larger bs-            larger (IntInterval k _) = k >= i-            larger NoInterval        = error "larger NoInterval"-    merge2 as bs = case FT.viewl bs of-        EmptyL                  -> as-        b@(Node i _) :< bs'     -> l >< b <| merge1 r bs'-          where-            (l, r) = FT.split larger as-            larger (IntInterval k _) = k > i-            larger NoInterval        = error "larger NoInterval"---- | /O(k log (n/\//k))/.  All intervals that intersect with the given--- interval, in lexicographical order.-intersections :: (Ord v) => Interval v -> IntervalMap v a -> [(Interval v, a)]-intersections i = inRange (low i) (high i)---- | /O(k log (n/\//k))/.  All intervals that contain the given interval,--- in lexicographical order.-dominators :: (Ord v) => Interval v -> IntervalMap v a -> [(Interval v, a)]-dominators i = inRange (high i) (low i)---- | /O(k log (n/\//k))/.  All intervals that contain the given point,--- in lexicographical order.-search :: (Ord v) => v -> IntervalMap v a -> [(Interval v, a)]-search p = inRange p p---- | /O(k log (n/\//k))/.  All intervals that intersect with the given--- interval, in lexicographical order.-inRange :: (Ord v) => v -> v -> IntervalMap v a -> [(Interval v, a)]-inRange lo hi (IntervalMap t) = matches (FT.takeUntil (greater hi) t)-  where-    matches xs  =  case FT.viewl (FT.dropUntil (atleast lo) xs) of-        EmptyL          ->  []-        Node i x :< xs' ->  (i, x) : matches xs'--atleast :: (Ord v) => v -> IntInterval v -> Bool-atleast k (IntInterval _ hi) = k <= hi-atleast _ NoInterval         = error "atleast NoInterval"--greater :: (Ord v) => v -> IntInterval v -> Bool-greater k (IntInterval i _) = low i > k-greater _ NoInterval        = error "greater NoInterval"--{---- Examples--mkMap :: (Ord v) => [(v, v, a)] -> IntervalMap v a-mkMap = foldr ins empty-  where-    ins (lo, hi, n) = insert (Interval lo hi) n--composers :: IntervalMap Int String-composers = mkMap [-    (1685, 1750, "Bach"),-    (1685, 1759, "Handel"),-    (1732, 1809, "Haydn"),-    (1756, 1791, "Mozart"),-    (1770, 1827, "Beethoven"),-    (1782, 1840, "Paganini"),-    (1797, 1828, "Schubert"),-    (1803, 1869, "Berlioz"),-    (1810, 1849, "Chopin"),-    (1833, 1897, "Brahms"),-    (1838, 1875, "Bizet")]--mathematicians :: IntervalMap Int String-mathematicians = mkMap [-    (1642, 1727, "Newton"),-    (1646, 1716, "Leibniz"),-    (1707, 1783, "Euler"),-    (1736, 1813, "Lagrange"),-    (1777, 1855, "Gauss"),-    (1811, 1831, "Galois")]--}
− HaskellWorks/Data/PriorityQueue/FingerTree.hs
@@ -1,181 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE MultiParamTypeClasses #-}-#if __GLASGOW_HASKELL__ >= 702-{-# LANGUAGE Safe #-}-#endif-#if __GLASGOW_HASKELL__ >= 710-{-# LANGUAGE AutoDeriveTypeable #-}-#endif--------------------------------------------------------------------------------- |--- Module      :  Data.PriorityQueue.FingerTree--- Copyright   :  (c) Ross Paterson 2008--- License     :  BSD-style--- Maintainer  :  R.Paterson@city.ac.uk--- Stability   :  experimental--- Portability :  non-portable (MPTCs and functional dependencies)------ Min-priority queues implemented using the 'FingerTree' type,--- following section 4.6 of------  * Ralf Hinze and Ross Paterson,---    \"Finger trees: a simple general-purpose data structure\",---    /Journal of Functional Programming/ 16:2 (2006) pp 197-217.---    <http://staff.city.ac.uk/~ross/papers/FingerTree.html>------ These have the same big-O complexity as skew heap implementations,--- but are approximately an order of magnitude slower.--- On the other hand, they are stable, so they can be used for fair--- queueing.  They are also shallower, so that 'fmap' consumes less--- space.------ An amortized running time is given for each operation, with /n/--- referring to the size of the priority queue.  These bounds hold even--- in a persistent (shared) setting.------ /Note/: Many of these operations have the same names as similar--- operations on lists in the "Prelude".  The ambiguity may be resolved--- using either qualification or the @hiding@ clause.-----------------------------------------------------------------------------------module HaskellWorks.Data.PriorityQueue.FingerTree (-    PQueue,-    -- * Construction-    empty,-    singleton,-    union,-    insert,-    add,-    fromList,-    -- * Deconstruction-    null,-    minView,-    minViewWithKey-    ) where--import qualified HaskellWorks.Data.FingerTree as FT-import HaskellWorks.Data.FingerTree (FingerTree, (<|), (|>), (><), ViewL(..), Measured(..))--import Control.Arrow ((***))-import Data.Foldable (Foldable(foldMap))-import Data.Monoid-import Prelude hiding (null)--data Entry k v = Entry k v--instance Functor (Entry k) where-    fmap f (Entry k v) = Entry k (f v)--instance Foldable (Entry k) where-    foldMap f (Entry _ v) = f v--data Prio k v = NoPrio | Prio k v--instance Ord k => Monoid (Prio k v) where-    mempty                  = NoPrio-    x `mappend` NoPrio      = x-    NoPrio `mappend` y      = y-    x@(Prio kx _) `mappend` y@(Prio ky _)-      | kx <= ky            = x-      | otherwise           = y--instance Ord k => Measured (Prio k v) (Entry k v) where-    measure (Entry k v) = Prio k v---- | Priority queues.-newtype PQueue k v = PQueue (FingerTree (Prio k v) (Entry k v))--instance Ord k => Functor (PQueue k) where-    fmap f (PQueue xs) = PQueue (FT.fmap' (fmap f) xs)--instance Ord k => Foldable (PQueue k) where-    foldMap f q = case minView q of-        Nothing -> mempty-        Just (v, q') -> f v `mappend` foldMap f q'--instance Ord k => Monoid (PQueue k v) where-    mempty = empty-    mappend = union---- | /O(1)/. The empty priority queue.-empty :: Ord k => PQueue k v-empty = PQueue FT.empty---- | /O(1)/. A singleton priority queue.-singleton :: Ord k => k -> v -> PQueue k v-singleton k v = PQueue (FT.singleton (Entry k v))---- | /O(log n)/. Add a (priority, value) pair to the front of a priority queue.------ * @'insert' k v q = 'union' ('singleton' k v) q@------ If @q@ contains entries with the same priority @k@, 'minView' of--- @'insert' k v q@ will return them after this one.-insert :: Ord k => k -> v -> PQueue k v -> PQueue k v-insert k v (PQueue q) = PQueue (Entry k v <| q)---- | /O(log n)/. Add a (priority, value) pair to the back of a priority queue.------ * @'add' k v q = 'union' q ('singleton' k v)@------ If @q@ contains entries with the same priority @k@, 'minView' of--- @'add' k v q@ will return them before this one.-add :: Ord k => k -> v -> PQueue k v -> PQueue k v-add k v (PQueue q) = PQueue (q |> Entry k v)---- | /O(log(min(n1,n2)))/. Concatenate two priority queues.--- 'union' is associative, with identity 'empty'.------ If there are entries with the same priority in both arguments, 'minView'--- of @'union' xs ys@ will return those from @xs@ before those from @ys@.-union :: Ord k => PQueue k v -> PQueue k v -> PQueue k v-union (PQueue xs) (PQueue ys) = PQueue (xs >< ys)---- | /O(n)/. Create a priority queue from a finite list of priorities--- and values.-fromList :: Ord k => [(k, v)] -> PQueue k v-fromList = foldr (uncurry insert) empty---- | /O(1)/. Is this the empty priority queue?-null :: Ord k => PQueue k v -> Bool-null (PQueue q) = FT.null q---- | /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.------  * @'minView' 'empty' = 'Nothing'@------  * @'minView' ('singleton' k v) = 'Just' (v, 'empty')@----minView :: Ord k => PQueue k v -> Maybe (v, PQueue k v)-minView q = fmap (snd *** id) (minViewWithKey q)---- | /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.------  * @'minViewWithKey' 'empty' = 'Nothing'@------  * @'minViewWithKey' ('singleton' k v) = 'Just' ((k, v), 'empty')@------  * If @'minViewWithKey' qi = 'Just' ((ki, vi), qi')@ and @k1 <= k2@,---    then @'minViewWithKey' ('union' q1 q2) = 'Just' ((k1, v1), 'union' q1' q2)@------  * If @'minViewWithKey' qi = 'Just' ((ki, vi), qi')@ and @k2 < k1@,---    then @'minViewWithKey' ('union' q1 q2) = 'Just' ((k2, v2), 'union' q1 q2')@----minViewWithKey :: Ord k => PQueue k v -> Maybe ((k, v), PQueue k v)-minViewWithKey (PQueue q)-  | FT.null q = Nothing-  | otherwise = Just ((k, v), case FT.viewl r of-    _ :< r' -> PQueue (l >< r')-    _ -> error "can't happen")-  where-    Prio k v = measure q-    (l, r) = FT.split (below k) q--below :: Ord k => k -> Prio k v -> Bool-below _ NoPrio = False-below k (Prio k' _) = k' <= k
hw-fingertree.cabal view
@@ -1,54 +1,79 @@-Name:           hw-fingertree-Version:        0.1.0.0-Cabal-Version:  >= 1.8-Copyright:      (c) 2006 Ross Paterson, Ralf Hinze-License:        BSD3-License-File:   LICENSE-Maintainer:     Ross Paterson <R.Paterson@city.ac.uk>-bug-reports:    http://hub.darcs.net/ross/fingertree/issues-Category:       Data Structures-Synopsis:       Generic finger-tree structure, with example instances-Description:-                A general sequence representation with arbitrary+-- This file has been generated from package.yaml by hpack version 0.20.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 8cd50b9741a1c8a2bcc9297a6ee8ba24104ddc058fb32364d45037c5f0958bf1++name:           hw-fingertree+version:        0.1.0.1+synopsis:       Generic finger-tree structure, with example instances+description:    A general sequence representation with arbitrary                 annotations, for use as a base for implementations of                 various collection types, with examples, as described                 in section 4 of                 .-                 * Ralf Hinze and Ross Paterson,-                   \"Finger trees: a simple general-purpose data structure\",-                   /Journal of Functional Programming/ 16:2 (2006) pp 197-217.-                   <http://staff.city.ac.uk/~ross/papers/FingerTree.html>+                * Ralf Hinze and Ross Paterson,+                \"Finger trees: a simple general-purpose data structure\",+                /Journal of Functional Programming/ 16:2 (2006) pp 197-217.+                <http://staff.city.ac.uk/~ross/papers/FingerTree.html>                 .                 For a tuned sequence type, see @Data.Sequence@ in the                 @containers@ package, which is a specialization of                 this structure.-Build-Type:     Simple+category:       Data Structures+homepage:       https://github.com/haskell-works/hw-fingertree#readme+bug-reports:    https://github.com/haskell-works/hw-fingertree/issues+maintainer:     John Ky <newhoggy@gmail.com>+copyright:      (c) 2006 Ross Paterson,+                Ralf Hinze,+                (c) 2017-2018 John Ky+license:        BSD3+license-file:   LICENSE+build-type:     Simple+cabal-version:  >= 1.10 -Source-Repository head-  Type: git-  Location: https://github.com/haskell-works/hw-fingertree+source-repository head+  type: git+  location: https://github.com/haskell-works/hw-fingertree -Library-  Build-Depends:  base < 6-                , deepseq-  Extensions:   MultiParamTypeClasses-                FunctionalDependencies-                FlexibleInstances-                UndecidableInstances-  Exposed-Modules:-                HaskellWorks.Data.FingerTree-                HaskellWorks.Data.IntervalMap.FingerTree-                HaskellWorks.Data.PriorityQueue.FingerTree+library+  hs-source-dirs:+      src+  build-depends:+      base <6+    , deepseq+  exposed-modules:+      HaskellWorks.Data.FingerTree+      HaskellWorks.Data.IntervalMap.FingerTree+      HaskellWorks.Data.PriorityQueue.FingerTree+  other-modules:+      Paths_hw_fingertree+  default-language: Haskell2010 -Test-suite ft-properties+test-suite hw-fingertree-tests   type: exitcode-stdio-1.0-  main-is: tests/ft-properties.hs+  main-is: Spec.hs+  hs-source-dirs:+      tests+      src   cpp-options: -DTESTING   build-depends:-                base >= 4.2 && < 6,-                deepseq,-                HUnit,-                QuickCheck,-                test-framework,-                test-framework-hunit,-                test-framework-quickcheck2+      HUnit+    , QuickCheck+    , base >=4.2 && <6+    , deepseq+    , hedgehog+    , hspec+    , hw-fingertree+    , hw-hspec-hedgehog+    , test-framework+    , test-framework-hunit+    , test-framework-quickcheck2+  other-modules:+      HaskellWorks.Data.FingerTree.Gen+      HaskellWorks.Data.FingerTreeSpec+      HaskellWorks.Data.FingerTree+      HaskellWorks.Data.IntervalMap.FingerTree+      HaskellWorks.Data.PriorityQueue.FingerTree+      Paths_hw_fingertree+  default-language: Haskell2010
+ src/HaskellWorks/Data/FingerTree.hs view
@@ -0,0 +1,878 @@+{-# LANGUAGE CPP                    #-}+{-# LANGUAGE DeriveAnyClass         #-}+{-# LANGUAGE DeriveGeneric          #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses  #-}+{-# LANGUAGE UndecidableInstances   #-}+#if __GLASGOW_HASKELL__ >= 702+{-# LANGUAGE Safe                   #-}+#endif+#if __GLASGOW_HASKELL__ >= 710+{-# LANGUAGE AutoDeriveTypeable     #-}+#endif+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.FingerTree+-- Copyright   :  (c) Ross Paterson, Ralf Hinze 2006+-- License     :  BSD-style+-- Maintainer  :  R.Paterson@city.ac.uk+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs and functional dependencies)+--+-- A general sequence representation with arbitrary annotations, for+-- use as a base for implementations of various collection types, as+-- described in section 4 of+--+--  * Ralf Hinze and Ross Paterson,+--    \"Finger trees: a simple general-purpose data structure\",+--    /Journal of Functional Programming/ 16:2 (2006) pp 197-217.+--    <http://staff.city.ac.uk/~ross/papers/FingerTree.html>+--+-- For a directly usable sequence type, see @Data.Sequence@, which is+-- a specialization of this structure.+--+-- An amortized running time is given for each operation, with /n/+-- referring to the length of the sequence.  These bounds hold even in+-- a persistent (shared) setting.+--+-- /Note/: Many of these operations have the same names as similar+-- operations on lists in the "Prelude".  The ambiguity may be resolved+-- using either qualification or the @hiding@ clause.+--+-----------------------------------------------------------------------------++module HaskellWorks.Data.FingerTree (+#if TESTING+    FingerTree(..), Digit(..), Node(..), deep, node2, node3,+#else+    FingerTree,+#endif+    Measured(..),+    -- * Construction+    empty, singleton,+    (<|), (|>), (><),+    fromList,+    -- * Deconstruction+    null,+    ViewL(..), ViewR(..), viewl, viewr,+    split, takeUntil, dropUntil,+    -- * Transformation+    reverse,+    fmap', fmapWithPos, unsafeFmap,+    traverse', traverseWithPos, unsafeTraverse+    -- * Example+    -- $example+    ) where++import Prelude hiding (null, reverse)++import Control.Applicative (Applicative (pure, (<*>)), (<$>))+import Control.DeepSeq+import Data.Foldable       (Foldable (foldMap), toList)+import Data.Monoid+import GHC.Generics        (Generic)++import qualified Data.Semigroup as S++infixr 5 ><+infixr 5 <|, :<+infixl 5 |>, :>++-- | View of the left end of a sequence.+data ViewL s a+    = EmptyL        -- ^ empty sequence+    | a :< s a      -- ^ leftmost element and the rest of the sequence+    deriving (Eq, Ord, Show, Read, Generic, NFData)++-- | View of the right end of a sequence.+data ViewR s a+    = EmptyR        -- ^ empty sequence+    | s a :> a      -- ^ the sequence minus the rightmost element,+                    -- and the rightmost element+    deriving (Eq, Ord, Show, Read, Generic, NFData)++instance Functor s => Functor (ViewL s) where+    fmap _ EmptyL    = EmptyL+    fmap f (x :< xs) = f x :< fmap f xs++instance Functor s => Functor (ViewR s) where+    fmap _ EmptyR    = EmptyR+    fmap f (xs :> x) = fmap f xs :> f x++instance Measured v a => S.Semigroup (FingerTree v a) where+  (<>) = (><)+  {-# INLINE (<>) #-}++-- | 'empty' and '><'.+instance Measured v a => Monoid (FingerTree v a) where+  mempty = empty+  {-# INLINE mempty #-}+  mappend = (><)+  {-# INLINE mappend #-}++-- Explicit Digit type (Exercise 1)++data Digit a+    = One a+    | Two a a+    | Three a a a+    | Four a a a a+    deriving (Show, Generic, NFData)++instance Foldable Digit where+    foldMap f (One a)        = f a+    foldMap f (Two a b)      = f a `mappend` f b+    foldMap f (Three a b c)  = f a `mappend` f b `mappend` f c+    foldMap f (Four a b c d) = f a `mappend` f b `mappend` f c `mappend` f d++-------------------+-- 4.1 Measurements+-------------------++-- | Things that can be measured.+class (Monoid v) => Measured v a | a -> v where+    measure :: a -> v++instance (Measured v a) => Measured v (Digit a) where+    measure = foldMap measure++---------------------------+-- 4.2 Caching measurements+---------------------------++data Node v a = Node2 !v a a | Node3 !v a a a+    deriving (Show, Generic, NFData)++instance Foldable (Node v) where+    foldMap f (Node2 _ a b)   = f a `mappend` f b+    foldMap f (Node3 _ a b c) = f a `mappend` f b `mappend` f c++node2        ::  (Measured v a) => a -> a -> Node v a+node2 a b    =   Node2 (measure a `mappend` measure b) a b++node3        ::  (Measured v a) => a -> a -> a -> Node v a+node3 a b c  =   Node3 (measure a `mappend` measure b `mappend` measure c) a b c++instance (Monoid v) => Measured v (Node v a) where+    measure (Node2 v _ _)   =  v+    measure (Node3 v _ _ _) =  v++nodeToDigit :: Node v a -> Digit a+nodeToDigit (Node2 _ a b)   = Two a b+nodeToDigit (Node3 _ a b c) = Three a b c++-- | A representation of a sequence of values of type @a@, allowing+-- access to the ends in constant time, and append and split in time+-- logarithmic in the size of the smaller piece.+--+-- The collection is also parameterized by a measure type @v@, which+-- is used to specify a position in the sequence for the 'split' operation.+-- The types of the operations enforce the constraint @'Measured' v a@,+-- which also implies that the type @v@ is determined by @a@.+--+-- A variety of abstract data types can be implemented by using different+-- element types and measurements.+data FingerTree v a+    = Empty+    | Single a+    | Deep !v !(Digit a) (FingerTree v (Node v a)) !(Digit a)+    deriving (+#if TESTING+    Show,+#endif+    Generic, NFData)++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+    measure (Deep v _ _ _) =  v++instance Foldable (FingerTree v) where+    foldMap _ Empty = mempty+    foldMap f (Single x) = f x+    foldMap f (Deep _ pr m sf) =+        foldMap f pr `mappend` foldMap (foldMap f) m `mappend` foldMap f sf++instance Eq a => Eq (FingerTree v a) where+    xs == ys = toList xs == toList ys++instance Ord a => Ord (FingerTree v a) where+    compare xs ys = compare (toList xs) (toList ys)++#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) =>+    (a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2+fmap' = mapTree++mapTree :: (Measured v2 a2) =>+    (a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2+mapTree _ Empty = Empty+mapTree f (Single x) = Single (f x)+mapTree f (Deep _ pr m sf) =+    deep (mapDigit f pr) (mapTree (mapNode f) m) (mapDigit f sf)++mapNode :: (Measured v2 a2) =>+    (a1 -> a2) -> Node v1 a1 -> Node v2 a2+mapNode f (Node2 _ a b)   = node2 (f a) (f b)+mapNode f (Node3 _ a b c) = node3 (f a) (f b) (f c)++mapDigit :: (a -> b) -> Digit a -> Digit b+mapDigit f (One a)        = One (f a)+mapDigit f (Two a b)      = Two (f a) (f b)+mapDigit f (Three a b c)  = Three (f a) (f b) (f c)+mapDigit f (Four a b c d) = Four (f a) (f b) (f c) (f d)++-- | Map all elements of the tree with a function that also takes the+-- measure of the prefix of the tree to the left of the element.+fmapWithPos :: (Measured v1 a1, Measured v2 a2) =>+    (v1 -> a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2+fmapWithPos f = mapWPTree f mempty++mapWPTree :: (Measured v1 a1, Measured v2 a2) =>+    (v1 -> a1 -> a2) -> v1 -> FingerTree v1 a1 -> FingerTree v2 a2+mapWPTree _ _ Empty = Empty+mapWPTree f v (Single x) = Single (f v x)+mapWPTree f v (Deep _ pr m sf) =+    deep (mapWPDigit f v pr)+         (mapWPTree (mapWPNode f) vpr m)+         (mapWPDigit f vm sf)+  where+    vpr     =  v    `mappend`  measure pr+    vm      =  vpr  `mappendVal` m++mapWPNode :: (Measured v1 a1, Measured v2 a2) =>+    (v1 -> a1 -> a2) -> v1 -> Node v1 a1 -> Node v2 a2+mapWPNode f v (Node2 _ a b) = node2 (f v a) (f va b)+  where+    va      = v `mappend` measure a+mapWPNode f v (Node3 _ a b c) = node3 (f v a) (f va b) (f vab c)+  where+    va      = v `mappend` measure a+    vab     = va `mappend` measure b++mapWPDigit :: (Measured v a) => (v -> a -> b) -> v -> Digit a -> Digit b+mapWPDigit f v (One a) = One (f v a)+mapWPDigit f v (Two a b) = Two (f v a) (f va b)+  where+    va      = v `mappend` measure a+mapWPDigit f v (Three a b c) = Three (f v a) (f va b) (f vab c)+  where+    va      = v `mappend` measure a+    vab     = va `mappend` measure b+mapWPDigit f v (Four a b c d) = Four (f v a) (f va b) (f vab c) (f vabc d)+  where+    va      = v `mappend` measure a+    vab     = va `mappend` measure b+    vabc    = vab `mappend` measure c++-- | Like 'fmap', but safe only if the function preserves the measure.+unsafeFmap :: (a -> b) -> FingerTree v a -> FingerTree v b+unsafeFmap _ Empty = Empty+unsafeFmap f (Single x) = Single (f x)+unsafeFmap f (Deep v pr m sf) =+    Deep v (mapDigit f pr) (unsafeFmap (unsafeFmapNode f) m) (mapDigit f sf)++unsafeFmapNode :: (a -> b) -> Node v a -> Node v b+unsafeFmapNode f (Node2 v a b)   = Node2 v (f a) (f b)+unsafeFmapNode f (Node3 v a b c) = Node3 v (f a) (f b) (f c)++-- | Like 'traverse', but with a more constrained type.+traverse' :: (Measured v1 a1, Measured v2 a2, Applicative f) =>+    (a1 -> f a2) -> FingerTree v1 a1 -> f (FingerTree v2 a2)+traverse' = traverseTree++traverseTree :: (Measured v2 a2, Applicative f) =>+    (a1 -> f a2) -> FingerTree v1 a1 -> f (FingerTree v2 a2)+traverseTree _ Empty = pure Empty+traverseTree f (Single x) = Single <$> f x+traverseTree f (Deep _ pr m sf) =+    deep <$> traverseDigit f pr <*> traverseTree (traverseNode f) m <*> traverseDigit f sf++traverseNode :: (Measured v2 a2, Applicative f) =>+    (a1 -> f a2) -> Node v1 a1 -> f (Node v2 a2)+traverseNode f (Node2 _ a b)   = node2 <$> f a <*> f b+traverseNode f (Node3 _ a b c) = node3 <$> f a <*> f b <*> f c++traverseDigit :: (Applicative f) => (a -> f b) -> Digit a -> f (Digit b)+traverseDigit f (One a)        = One <$> f a+traverseDigit f (Two a b)      = Two <$> f a <*> f b+traverseDigit f (Three a b c)  = Three <$> f a <*> f b <*> f c+traverseDigit f (Four a b c d) = Four <$> f a <*> f b <*> f c <*> f d++-- | Traverse the tree with a function that also takes the+-- measure of the prefix of the tree to the left of the element.+traverseWithPos :: (Measured v1 a1, Measured v2 a2, Applicative f) =>+    (v1 -> a1 -> f a2) -> FingerTree v1 a1 -> f (FingerTree v2 a2)+traverseWithPos f = traverseWPTree f mempty++traverseWPTree :: (Measured v1 a1, Measured v2 a2, Applicative f) =>+    (v1 -> a1 -> f a2) -> v1 -> FingerTree v1 a1 -> f (FingerTree v2 a2)+traverseWPTree _ _ Empty = pure Empty+traverseWPTree f v (Single x) = Single <$> f v x+traverseWPTree f v (Deep _ pr m sf) =+    deep <$> traverseWPDigit f v pr <*> traverseWPTree (traverseWPNode f) vpr m <*> traverseWPDigit f vm sf+  where+    vpr     =  v    `mappend`  measure pr+    vm      =  vpr  `mappendVal` m++traverseWPNode :: (Measured v1 a1, Measured v2 a2, Applicative f) =>+    (v1 -> a1 -> f a2) -> v1 -> Node v1 a1 -> f (Node v2 a2)+traverseWPNode f v (Node2 _ a b) = node2 <$> f v a <*> f va b+  where+    va      = v `mappend` measure a+traverseWPNode f v (Node3 _ a b c) = node3 <$> f v a <*> f va b <*> f vab c+  where+    va      = v `mappend` measure a+    vab     = va `mappend` measure b++traverseWPDigit :: (Measured v a, Applicative f) =>+    (v -> a -> f b) -> v -> Digit a -> f (Digit b)+traverseWPDigit f v (One a) = One <$> f v a+traverseWPDigit f v (Two a b) = Two <$> f v a <*> f va b+  where+    va      = v `mappend` measure a+traverseWPDigit f v (Three a b c) = Three <$> f v a <*> f va b <*> f vab c+  where+    va      = v `mappend` measure a+    vab     = va `mappend` measure b+traverseWPDigit f v (Four a b c d) = Four <$> f v a <*> f va b <*> f vab c <*> f vabc d+  where+    va      = v `mappend` measure a+    vab     = va `mappend` measure b+    vabc    = vab `mappend` measure c++-- | Like 'traverse', but safe only if the function preserves the measure.+unsafeTraverse :: (Applicative f) =>+    (a -> f b) -> FingerTree v a -> f (FingerTree v b)+unsafeTraverse _ Empty = pure Empty+unsafeTraverse f (Single x) = Single <$> f x+unsafeTraverse f (Deep v pr m sf) =+    Deep v <$> traverseDigit f pr <*> unsafeTraverse (unsafeTraverseNode f) m <*> traverseDigit f sf++unsafeTraverseNode :: (Applicative f) =>+    (a -> f b) -> Node v a -> f (Node v b)+unsafeTraverseNode f (Node2 v a b)   = Node2 v <$> f a <*> f b+unsafeTraverseNode f (Node3 v a b c) = Node3 v <$> f a <*> f b <*> f c++-----------------------------------------------------+-- 4.3 Construction, deconstruction and concatenation+-----------------------------------------------------++-- | /O(1)/. The empty sequence.+empty :: Measured v a => FingerTree v a+empty = Empty++-- | /O(1)/. A singleton sequence.+singleton :: Measured v a => a -> FingerTree v a+singleton = Single++-- | /O(n)/. Create a sequence from a finite list of elements.+fromList :: (Measured v a) => [a] -> FingerTree v a+fromList = foldr (<|) Empty++-- | /O(1)/. Add an element to the left end of a sequence.+-- Mnemonic: a triangle with the single element at the pointy end.+(<|) :: (Measured v a) => a -> FingerTree v a -> FingerTree v a+a <| Empty              =  Single a+a <| Single b           =  deep (One a) Empty (One b)+a <| Deep v (Four b c d e) m sf = m `seq`+    Deep (measure a `mappend` v) (Two a b) (node3 c d e <| m) sf+a <| Deep v pr m sf     =+    Deep (measure a `mappend` v) (consDigit a pr) m sf++consDigit :: a -> Digit a -> Digit a+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.+(|>) :: (Measured v a) => FingerTree v a -> a -> FingerTree v a+Empty |> a              =  Single a+Single a |> b           =  deep (One a) Empty (One b)+Deep v pr m (Four a b c d) |> e = m `seq`+    Deep (v `mappend` measure e) pr (m |> node3 a b c) (Two d e)+Deep v pr m sf |> x     =+    Deep (v `mappend` measure x) pr m (snocDigit sf x)++snocDigit :: Digit a -> a -> Digit a+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+null Empty = True+null _     = False++-- | /O(1)/. Analyse the left end of a sequence.+viewl :: (Measured v a) => FingerTree v a -> ViewL (FingerTree v) a+viewl Empty                 =  EmptyL+viewl (Single x)            =  x :< Empty+viewl (Deep _ (One x) m sf) =  x :< rotL m sf+viewl (Deep _ pr m sf)      =  lheadDigit pr :< deep (ltailDigit pr) m sf++rotL :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> FingerTree v a+rotL m sf      =   case viewl m of+    EmptyL  ->  digitToTree sf+    a :< m' ->  Deep (measure m `mappend` measure sf) (nodeToDigit a) m' sf++lheadDigit :: Digit a -> a+lheadDigit (One a)        = a+lheadDigit (Two a _)      = a+lheadDigit (Three a _ _)  = a+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++-- | /O(1)/. Analyse the right end of a sequence.+viewr :: (Measured v a) => FingerTree v a -> ViewR (FingerTree v) a+viewr Empty                 =  EmptyR+viewr (Single x)            =  Empty :> x+viewr (Deep _ pr m (One x)) =  rotR pr m :> x+viewr (Deep _ pr m sf)      =  deep pr m (rtailDigit sf) :> rheadDigit sf++rotR :: (Measured v a) => Digit a -> FingerTree v (Node v a) -> FingerTree v a+rotR pr m = case viewr m of+    EmptyR  ->  digitToTree pr+    m' :> a ->  Deep (measure pr `mappendVal` m) pr m' (nodeToDigit a)++rheadDigit :: Digit a -> a+rheadDigit (One a)        = a+rheadDigit (Two _ b)      = b+rheadDigit (Three _ _ c)  = c+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++digitToTree :: (Measured v a) => Digit a -> FingerTree v a+digitToTree (One a)        = Single a+digitToTree (Two a b)      = deep (One a) Empty (One b)+digitToTree (Three a b c)  = deep (Two a b) Empty (One c)+digitToTree (Four a b c d) = deep (Two a b) Empty (Two c d)++----------------+-- Concatenation+----------------++-- | /O(log(min(n1,n2)))/. Concatenate two sequences.+(><) :: (Measured v a) => FingerTree v a -> FingerTree v a -> FingerTree v a+(><) =  appendTree0++appendTree0 :: (Measured v a) => FingerTree v a -> FingerTree v a -> FingerTree v a+appendTree0 Empty xs =+    xs+appendTree0 xs Empty =+    xs+appendTree0 (Single x) xs =+    x <| xs+appendTree0 xs (Single x) =+    xs |> x+appendTree0 (Deep _ pr1 m1 sf1) (Deep _ pr2 m2 sf2) =+    deep pr1 (addDigits0 m1 sf1 pr2 m2) sf2++addDigits0 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)+addDigits0 m1 (One a) (One b) m2 =+    appendTree1 m1 (node2 a b) m2+addDigits0 m1 (One a) (Two b c) m2 =+    appendTree1 m1 (node3 a b c) m2+addDigits0 m1 (One a) (Three b c d) m2 =+    appendTree2 m1 (node2 a b) (node2 c d) m2+addDigits0 m1 (One a) (Four b c d e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits0 m1 (Two a b) (One c) m2 =+    appendTree1 m1 (node3 a b c) m2+addDigits0 m1 (Two a b) (Two c d) m2 =+    appendTree2 m1 (node2 a b) (node2 c d) m2+addDigits0 m1 (Two a b) (Three c d e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits0 m1 (Two a b) (Four c d e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits0 m1 (Three a b c) (One d) m2 =+    appendTree2 m1 (node2 a b) (node2 c d) m2+addDigits0 m1 (Three a b c) (Two d e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits0 m1 (Three a b c) (Three d e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits0 m1 (Three a b c) (Four d e f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits0 m1 (Four a b c d) (One e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits0 m1 (Four a b c d) (Two e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits0 m1 (Four a b c d) (Three e f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits0 m1 (Four a b c d) (Four e f g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2++appendTree1 :: (Measured v a) => FingerTree v a -> a -> FingerTree v a -> FingerTree v a+appendTree1 Empty a xs =+    a <| xs+appendTree1 xs a Empty =+    xs |> a+appendTree1 (Single x) a xs =+    x <| a <| xs+appendTree1 xs a (Single x) =+    xs |> a |> x+appendTree1 (Deep _ pr1 m1 sf1) a (Deep _ pr2 m2 sf2) =+    deep pr1 (addDigits1 m1 sf1 a pr2 m2) sf2++addDigits1 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)+addDigits1 m1 (One a) b (One c) m2 =+    appendTree1 m1 (node3 a b c) m2+addDigits1 m1 (One a) b (Two c d) m2 =+    appendTree2 m1 (node2 a b) (node2 c d) m2+addDigits1 m1 (One a) b (Three c d e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits1 m1 (One a) b (Four c d e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits1 m1 (Two a b) c (One d) m2 =+    appendTree2 m1 (node2 a b) (node2 c d) m2+addDigits1 m1 (Two a b) c (Two d e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits1 m1 (Two a b) c (Three d e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits1 m1 (Two a b) c (Four d e f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits1 m1 (Three a b c) d (One e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits1 m1 (Three a b c) d (Two e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits1 m1 (Three a b c) d (Three e f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits1 m1 (Three a b c) d (Four e f g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits1 m1 (Four a b c d) e (One f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits1 m1 (Four a b c d) e (Two f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits1 m1 (Four a b c d) e (Three f g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits1 m1 (Four a b c d) e (Four f g h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2++appendTree2 :: (Measured v a) => FingerTree v a -> a -> a -> FingerTree v a -> FingerTree v a+appendTree2 Empty a b xs =+    a <| b <| xs+appendTree2 xs a b Empty =+    xs |> a |> b+appendTree2 (Single x) a b xs =+    x <| a <| b <| xs+appendTree2 xs a b (Single x) =+    xs |> a |> b |> x+appendTree2 (Deep _ pr1 m1 sf1) a b (Deep _ pr2 m2 sf2) =+    deep pr1 (addDigits2 m1 sf1 a b pr2 m2) sf2++addDigits2 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> a -> a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)+addDigits2 m1 (One a) b c (One d) m2 =+    appendTree2 m1 (node2 a b) (node2 c d) m2+addDigits2 m1 (One a) b c (Two d e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits2 m1 (One a) b c (Three d e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits2 m1 (One a) b c (Four d e f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits2 m1 (Two a b) c d (One e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits2 m1 (Two a b) c d (Two e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits2 m1 (Two a b) c d (Three e f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits2 m1 (Two a b) c d (Four e f g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits2 m1 (Three a b c) d e (One f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits2 m1 (Three a b c) d e (Two f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits2 m1 (Three a b c) d e (Three f g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits2 m1 (Three a b c) d e (Four f g h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits2 m1 (Four a b c d) e f (One g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits2 m1 (Four a b c d) e f (Two g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits2 m1 (Four a b c d) e f (Three g h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits2 m1 (Four a b c d) e f (Four g h i j) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2++appendTree3 :: (Measured v a) => FingerTree v a -> a -> a -> a -> FingerTree v a -> FingerTree v a+appendTree3 Empty a b c xs =+    a <| b <| c <| xs+appendTree3 xs a b c Empty =+    xs |> a |> b |> c+appendTree3 (Single x) a b c xs =+    x <| a <| b <| c <| xs+appendTree3 xs a b c (Single x) =+    xs |> a |> b |> c |> x+appendTree3 (Deep _ pr1 m1 sf1) a b c (Deep _ pr2 m2 sf2) =+    deep pr1 (addDigits3 m1 sf1 a b c pr2 m2) sf2++addDigits3 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> a -> a -> a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)+addDigits3 m1 (One a) b c d (One e) m2 =+    appendTree2 m1 (node3 a b c) (node2 d e) m2+addDigits3 m1 (One a) b c d (Two e f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits3 m1 (One a) b c d (Three e f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits3 m1 (One a) b c d (Four e f g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits3 m1 (Two a b) c d e (One f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits3 m1 (Two a b) c d e (Two f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits3 m1 (Two a b) c d e (Three f g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits3 m1 (Two a b) c d e (Four f g h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits3 m1 (Three a b c) d e f (One g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits3 m1 (Three a b c) d e f (Two g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits3 m1 (Three a b c) d e f (Three g h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits3 m1 (Three a b c) d e f (Four g h i j) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2+addDigits3 m1 (Four a b c d) e f g (One h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits3 m1 (Four a b c d) e f g (Two h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits3 m1 (Four a b c d) e f g (Three h i j) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2+addDigits3 m1 (Four a b c d) e f g (Four h i j k) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node3 g h i) (node2 j k) m2++appendTree4 :: (Measured v a) => FingerTree v a -> a -> a -> a -> a -> FingerTree v a -> FingerTree v a+appendTree4 Empty a b c d xs =+    a <| b <| c <| d <| xs+appendTree4 xs a b c d Empty =+    xs |> a |> b |> c |> d+appendTree4 (Single x) a b c d xs =+    x <| a <| b <| c <| d <| xs+appendTree4 xs a b c d (Single x) =+    xs |> a |> b |> c |> d |> x+appendTree4 (Deep _ pr1 m1 sf1) a b c d (Deep _ pr2 m2 sf2) =+    deep pr1 (addDigits4 m1 sf1 a b c d pr2 m2) sf2++addDigits4 :: (Measured v a) => FingerTree v (Node v a) -> Digit a -> a -> a -> a -> a -> Digit a -> FingerTree v (Node v a) -> FingerTree v (Node v a)+addDigits4 m1 (One a) b c d e (One f) m2 =+    appendTree2 m1 (node3 a b c) (node3 d e f) m2+addDigits4 m1 (One a) b c d e (Two f g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits4 m1 (One a) b c d e (Three f g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits4 m1 (One a) b c d e (Four f g h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits4 m1 (Two a b) c d e f (One g) m2 =+    appendTree3 m1 (node3 a b c) (node2 d e) (node2 f g) m2+addDigits4 m1 (Two a b) c d e f (Two g h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits4 m1 (Two a b) c d e f (Three g h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits4 m1 (Two a b) c d e f (Four g h i j) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2+addDigits4 m1 (Three a b c) d e f g (One h) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node2 g h) m2+addDigits4 m1 (Three a b c) d e f g (Two h i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits4 m1 (Three a b c) d e f g (Three h i j) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2+addDigits4 m1 (Three a b c) d e f g (Four h i j k) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node3 g h i) (node2 j k) m2+addDigits4 m1 (Four a b c d) e f g h (One i) m2 =+    appendTree3 m1 (node3 a b c) (node3 d e f) (node3 g h i) m2+addDigits4 m1 (Four a b c d) e f g h (Two i j) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node2 g h) (node2 i j) m2+addDigits4 m1 (Four a b c d) e f g h (Three i j k) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node3 g h i) (node2 j k) m2+addDigits4 m1 (Four a b c d) e f g h (Four i j k l) m2 =+    appendTree4 m1 (node3 a b c) (node3 d e f) (node3 g h i) (node3 j k l) m2++----------------+-- 4.4 Splitting+----------------++-- | /O(log(min(i,n-i)))/. Split a sequence at a point where the predicate+-- on the accumulated measure changes from 'False' to 'True'.+--+-- For predictable results, one should ensure that there is only one such+-- point, i.e. that the predicate is /monotonic/.+split ::  (Measured v a) =>+      (v -> Bool) -> FingerTree v a -> (FingerTree v a, FingerTree v a)+split _ Empty  =  (Empty, Empty)+split p xs+  | p (measure xs) =  (l, x <| r)+  | otherwise   =  (xs, Empty)+  where+    Split l x r = splitTree p mempty xs++-- | /O(log(min(i,n-i)))/.+-- Given a monotonic predicate @p@, @'takeUntil' p t@ is the largest+-- prefix of @t@ whose measure does not satisfy @p@.+--+-- *  @'takeUntil' p t = 'fst' ('split' p t)@+takeUntil :: (Measured v a) => (v -> Bool) -> FingerTree v a -> FingerTree v a+takeUntil p  =  fst . split p++-- | /O(log(min(i,n-i)))/.+-- Given a monotonic predicate @p@, @'dropUntil' p t@ is the rest of @t@+-- after removing the largest prefix whose measure does not satisfy @p@.+--+-- * @'dropUntil' p t = 'snd' ('split' p t)@+dropUntil :: (Measured v a) => (v -> Bool) -> FingerTree v a -> FingerTree v a+dropUntil p  =  snd . split p++data Split t a = Split t a t++splitTree :: (Measured v a) =>+    (v -> Bool) -> v -> FingerTree v a -> Split (FingerTree v a) a+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)+  | p vm        =  let  Split ml xs mr  =  splitTree p vpr m+                        Split l x r     =  splitNode p (vpr `mappendVal` ml) xs+                   in   Split (deepR pr  ml l) x (deepL r mr sf)+  | otherwise   =  let  Split l x r     =  splitDigit p vm sf+                   in   Split (deepR pr  m  l) x (maybe Empty digitToTree r)+  where+    vpr     =  i    `mappend`  measure pr+    vm      =  vpr  `mappendVal` m++-- Avoid relying on right identity (cf Exercise 7)+mappendVal :: (Measured v a) => v -> FingerTree v a -> v+mappendVal v Empty = v+mappendVal v t     = v `mappend` measure t++deepL :: (Measured v a) =>+    Maybe (Digit a) -> FingerTree v (Node v a) -> Digit a -> FingerTree v a+deepL Nothing m sf   =   rotL m sf+deepL (Just pr) m sf =   deep pr m sf++deepR :: (Measured v a) =>+    Digit a -> FingerTree v (Node v a) -> Maybe (Digit a) -> FingerTree v a+deepR pr m Nothing   =   rotR pr m+deepR pr m (Just sf) =   deep pr m sf++splitNode :: (Measured v a) => (v -> Bool) -> v -> Node v a ->+    Split (Maybe (Digit a)) a+splitNode p i (Node2 _ a b)+  | p va        = Split Nothing a (Just (One b))+  | otherwise   = Split (Just (One a)) b Nothing+  where+    va      = i `mappend` measure a+splitNode p i (Node3 _ a b c)+  | p va        = Split Nothing a (Just (Two b c))+  | p vab       = Split (Just (One a)) b (Just (One c))+  | otherwise   = Split (Just (Two a b)) c Nothing+  where+    va      = i `mappend` measure a+    vab     = va `mappend` measure b++splitDigit :: (Measured v a) => (v -> Bool) -> v -> Digit a ->+    Split (Maybe (Digit a)) a+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+  where+    va      = i `mappend` measure a+splitDigit p i (Three a b c)+  | p va        = Split Nothing a (Just (Two b c))+  | p vab       = Split (Just (One a)) b (Just (One c))+  | otherwise   = Split (Just (Two a b)) c Nothing+  where+    va      = i `mappend` measure a+    vab     = va `mappend` measure b+splitDigit p i (Four a b c d)+  | p va        = Split Nothing a (Just (Three b c d))+  | p vab       = Split (Just (One a)) b (Just (Two c d))+  | p vabc      = Split (Just (Two a b)) c (Just (One d))+  | otherwise   = Split (Just (Three a b c)) d Nothing+  where+    va      = i `mappend` measure a+    vab     = va `mappend` measure b+    vabc    = vab `mappend` measure c++------------------+-- Transformations+------------------++-- | /O(n)/. The reverse of a sequence.+reverse :: (Measured v a) => FingerTree v a -> FingerTree v a+reverse = reverseTree id++reverseTree :: (Measured v2 a2) => (a1 -> a2) -> FingerTree v1 a1 -> FingerTree v2 a2+reverseTree _ Empty = Empty+reverseTree f (Single x) = Single (f x)+reverseTree f (Deep _ pr m sf) =+    deep (reverseDigit f sf) (reverseTree (reverseNode f) m) (reverseDigit f pr)++reverseNode :: (Measured v2 a2) => (a1 -> a2) -> Node v1 a1 -> Node v2 a2+reverseNode f (Node2 _ a b)   = node2 (f b) (f a)+reverseNode f (Node3 _ a b c) = node3 (f c) (f b) (f a)++reverseDigit :: (a -> b) -> Digit a -> Digit b+reverseDigit f (One a)        = One (f a)+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++Particular abstract data types may be implemented by defining+element types with suitable 'Measured' instances.++(from section 4.5 of the paper)+Simple sequences can be implemented using a 'Sum' monoid as a measure:++> newtype Elem a = Elem { getElem :: a }+>+> instance Measured (Sum Int) (Elem a) where+>     measure (Elem _) = Sum 1+>+> newtype Seq a = Seq (FingerTree (Sum Int) (Elem a))++Then the measure of a subsequence is simply its length.+This representation supports log-time extraction of subsequences:++> take :: Int -> Seq a -> Seq a+> take k (Seq xs) = Seq (takeUntil (> Sum k) xs)+>+> drop :: Int -> Seq a -> Seq a+> drop k (Seq xs) = Seq (dropUntil (> Sum k) xs)++The module @Data.Sequence@ is an optimized instantiation of this type.++For further examples, see "Data.IntervalMap.FingerTree" and+"Data.PriorityQueue.FingerTree".++-}
+ src/HaskellWorks/Data/IntervalMap/FingerTree.hs view
@@ -0,0 +1,235 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE DeriveAnyClass        #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE MultiParamTypeClasses #-}+#if __GLASGOW_HASKELL__ >= 702+{-# LANGUAGE Safe                  #-}+#endif+#if __GLASGOW_HASKELL__ >= 710+{-# LANGUAGE AutoDeriveTypeable    #-}+#endif+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.PriorityQueue.FingerTree+-- Copyright   :  (c) Ross Paterson 2008+-- License     :  BSD-style+-- Maintainer  :  R.Paterson@city.ac.uk+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs and functional dependencies)+--+-- Interval maps implemented using the 'FingerTree' type, following+-- section 4.8 of+--+--  * Ralf Hinze and Ross Paterson,+--    \"Finger trees: a simple general-purpose data structure\",+--    /Journal of Functional Programming/ 16:2 (2006) pp 197-217.+--    <http://staff.city.ac.uk/~ross/papers/FingerTree.html>+--+-- An amortized running time is given for each operation, with /n/+-- referring to the size of the priority queue.  These bounds hold even+-- in a persistent (shared) setting.+--+-- /Note/: Many of these operations have the same names as similar+-- operations on lists in the "Prelude".  The ambiguity may be resolved+-- using either qualification or the @hiding@ clause.+--+-----------------------------------------------------------------------------++module HaskellWorks.Data.IntervalMap.FingerTree (+    -- * Intervals+    Interval(..), point,+    -- * Interval maps+    IntervalMap(..), empty, singleton, insert, union,+    -- * Searching+    search, intersections, dominators+    ) where++import Control.Applicative          ((<$>))+import Control.DeepSeq+import Data.Foldable                (Foldable (foldMap))+import Data.Monoid+import Data.Traversable             (Traversable (traverse))+import GHC.Generics+import HaskellWorks.Data.FingerTree (FingerTree, Measured (..), ViewL (..), (<|), (><))++import qualified Data.Semigroup               as S+import qualified HaskellWorks.Data.FingerTree as FT++----------------------------------+-- 4.8 Application: interval trees+----------------------------------++-- | A closed interval.  The lower bound should be less than or equal+-- to the higher bound.+data Interval v = Interval { low :: v, high :: v }+    deriving (Eq, Ord, Show, Generic, NFData)++-- | An interval in which the lower and upper bounds are equal.+point :: v -> Interval v+point v = Interval v v++data Node v a = Node (Interval v) a deriving (Generic, NFData)++instance Functor (Node v) where+    fmap f (Node i x) = Node i (f x)++instance Foldable (Node v) where+    foldMap f (Node _ x) = f x++instance Traversable (Node v) where+    traverse f (Node i x) = Node i <$> f x++-- rightmost interval (including largest lower bound) and largest upper bound.+data IntInterval v = NoInterval | IntInterval (Interval v) v deriving (Generic, NFData)++appendInterval :: Ord v => IntInterval v -> IntInterval v -> IntInterval v+appendInterval (NoInterval       ) (i                   ) = i+appendInterval (i                ) (NoInterval          ) = i+appendInterval (IntInterval _ hi1) (IntInterval int2 hi2) = IntInterval int2 (max hi1 hi2)+{-# INLINE appendInterval #-}++instance Ord v => S.Semigroup (IntInterval v) where+  (<>) = appendInterval+  {-# INLINE (<>) #-}++instance Ord v => Monoid (IntInterval v) where+  mempty = NoInterval+  {-# INLINE mempty #-}+  mappend = appendInterval+  {-# INLINE mappend #-}++instance (Ord v) => Measured (IntInterval v) (Node v a) where+    measure (Node i _) = IntInterval i (high i)++-- | Map of closed intervals, possibly with duplicates.+-- The 'Foldable' and 'Traversable' instances process the intervals in+-- lexicographical order.+newtype IntervalMap v a =+    IntervalMap (FingerTree (IntInterval v) (Node v a))+    deriving (Generic, NFData)+-- ordered lexicographically by interval++instance Functor (IntervalMap v) where+    fmap f (IntervalMap t) = IntervalMap (FT.unsafeFmap (fmap f) t)++instance Foldable (IntervalMap v) where+    foldMap f (IntervalMap t) = foldMap (foldMap f) t++instance Traversable (IntervalMap v) where+    traverse f (IntervalMap t) =+        IntervalMap <$> FT.unsafeTraverse (traverse f) t++instance (Ord v) => S.Semigroup (IntervalMap v a) where+  (<>) = union+  {-# INLINE (<>) #-}++-- | 'empty' and 'union'.+instance (Ord v) => Monoid (IntervalMap v a) where+    mempty = empty+    {-# INLINE mempty #-}+    mappend = union+    {-# INLINE mappend #-}++-- | /O(1)/.  The empty interval map.+empty :: (Ord v) => IntervalMap v a+empty = IntervalMap FT.empty++-- | /O(1)/.  Interval map with a single entry.+singleton :: (Ord v) => Interval v -> a -> IntervalMap v a+singleton i x = IntervalMap (FT.singleton (Node i x))++-- | /O(log n)/.  Insert an interval into a map.+-- The map may contain duplicate intervals; the new entry will be inserted+-- before any existing entries for the same interval.+insert :: (Ord v) => Interval v -> a -> IntervalMap v a -> IntervalMap v a+insert (Interval lo hi) _ m | lo > hi = m+insert i x (IntervalMap t) = IntervalMap (l >< Node i x <| r)+  where+    (l, r) = FT.split larger t+    larger (IntInterval k _) = k >= i+    larger NoInterval        = error "larger NoInterval"++-- | /O(m log (n/\//m))/.  Merge two interval maps.+-- The map may contain duplicate intervals; entries with equal intervals+-- are kept in the original order.+union  ::  (Ord v) => IntervalMap v a -> IntervalMap v a -> IntervalMap v a+union (IntervalMap xs) (IntervalMap ys) = IntervalMap (merge1 xs ys)+  where+    merge1 as bs = case FT.viewl as of+        EmptyL                  -> bs+        a@(Node i _) :< as'     -> l >< a <| merge2 as' r+          where+            (l, r) = FT.split larger bs+            larger (IntInterval k _) = k >= i+            larger NoInterval        = error "larger NoInterval"+    merge2 as bs = case FT.viewl bs of+        EmptyL                  -> as+        b@(Node i _) :< bs'     -> l >< b <| merge1 r bs'+          where+            (l, r) = FT.split larger as+            larger (IntInterval k _) = k > i+            larger NoInterval        = error "larger NoInterval"++-- | /O(k log (n/\//k))/.  All intervals that intersect with the given+-- interval, in lexicographical order.+intersections :: (Ord v) => Interval v -> IntervalMap v a -> [(Interval v, a)]+intersections i = inRange (low i) (high i)++-- | /O(k log (n/\//k))/.  All intervals that contain the given interval,+-- in lexicographical order.+dominators :: (Ord v) => Interval v -> IntervalMap v a -> [(Interval v, a)]+dominators i = inRange (high i) (low i)++-- | /O(k log (n/\//k))/.  All intervals that contain the given point,+-- in lexicographical order.+search :: (Ord v) => v -> IntervalMap v a -> [(Interval v, a)]+search p = inRange p p++-- | /O(k log (n/\//k))/.  All intervals that intersect with the given+-- interval, in lexicographical order.+inRange :: (Ord v) => v -> v -> IntervalMap v a -> [(Interval v, a)]+inRange lo hi (IntervalMap t) = matches (FT.takeUntil (greater hi) t)+  where+    matches xs  =  case FT.viewl (FT.dropUntil (atleast lo) xs) of+        EmptyL          ->  []+        Node i x :< xs' ->  (i, x) : matches xs'++atleast :: (Ord v) => v -> IntInterval v -> Bool+atleast k (IntInterval _ hi) = k <= hi+atleast _ NoInterval         = error "atleast NoInterval"++greater :: (Ord v) => v -> IntInterval v -> Bool+greater k (IntInterval i _) = low i > k+greater _ NoInterval        = error "greater NoInterval"++{-+-- Examples++mkMap :: (Ord v) => [(v, v, a)] -> IntervalMap v a+mkMap = foldr ins empty+  where+    ins (lo, hi, n) = insert (Interval lo hi) n++composers :: IntervalMap Int String+composers = mkMap [+    (1685, 1750, "Bach"),+    (1685, 1759, "Handel"),+    (1732, 1809, "Haydn"),+    (1756, 1791, "Mozart"),+    (1770, 1827, "Beethoven"),+    (1782, 1840, "Paganini"),+    (1797, 1828, "Schubert"),+    (1803, 1869, "Berlioz"),+    (1810, 1849, "Chopin"),+    (1833, 1897, "Brahms"),+    (1838, 1875, "Bizet")]++mathematicians :: IntervalMap Int String+mathematicians = mkMap [+    (1642, 1727, "Newton"),+    (1646, 1716, "Leibniz"),+    (1707, 1783, "Euler"),+    (1736, 1813, "Lagrange"),+    (1777, 1855, "Gauss"),+    (1811, 1831, "Galois")]+-}
+ src/HaskellWorks/Data/PriorityQueue/FingerTree.hs view
@@ -0,0 +1,196 @@+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE MultiParamTypeClasses #-}+#if __GLASGOW_HASKELL__ >= 702+{-# LANGUAGE Safe                  #-}+#endif+#if __GLASGOW_HASKELL__ >= 710+{-# LANGUAGE AutoDeriveTypeable    #-}+#endif+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.PriorityQueue.FingerTree+-- Copyright   :  (c) Ross Paterson 2008+-- License     :  BSD-style+-- Maintainer  :  R.Paterson@city.ac.uk+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs and functional dependencies)+--+-- Min-priority queues implemented using the 'FingerTree' type,+-- following section 4.6 of+--+--  * Ralf Hinze and Ross Paterson,+--    \"Finger trees: a simple general-purpose data structure\",+--    /Journal of Functional Programming/ 16:2 (2006) pp 197-217.+--    <http://staff.city.ac.uk/~ross/papers/FingerTree.html>+--+-- These have the same big-O complexity as skew heap implementations,+-- but are approximately an order of magnitude slower.+-- On the other hand, they are stable, so they can be used for fair+-- queueing.  They are also shallower, so that 'fmap' consumes less+-- space.+--+-- An amortized running time is given for each operation, with /n/+-- referring to the size of the priority queue.  These bounds hold even+-- in a persistent (shared) setting.+--+-- /Note/: Many of these operations have the same names as similar+-- operations on lists in the "Prelude".  The ambiguity may be resolved+-- using either qualification or the @hiding@ clause.+--+-----------------------------------------------------------------------------++module HaskellWorks.Data.PriorityQueue.FingerTree (+    PQueue,+    -- * Construction+    empty,+    singleton,+    union,+    insert,+    add,+    fromList,+    -- * Deconstruction+    null,+    minView,+    minViewWithKey+    ) where++import Control.Arrow                ((***))+import Data.Foldable                (Foldable (foldMap))+import Data.Monoid+import HaskellWorks.Data.FingerTree (FingerTree, Measured (..), ViewL (..), (<|), (><), (|>))+import Prelude                      hiding (null)++import qualified Data.Semigroup               as S+import qualified HaskellWorks.Data.FingerTree as FT++data Entry k v = Entry k v++instance Functor (Entry k) where+    fmap f (Entry k v) = Entry k (f v)++instance Foldable (Entry k) where+    foldMap f (Entry _ v) = f v++data Prio k v = NoPrio | Prio k v++appendPrio :: Ord k => Prio k v -> Prio k v -> Prio k v+appendPrio x             NoPrio        = x+appendPrio NoPrio        y             = y+appendPrio x@(Prio kx _) y@(Prio ky _) = if kx <= ky then x else y+{-# INLINE appendPrio #-}++instance Ord k => S.Semigroup (Prio k v) where+  (<>) = appendPrio+  {-# INLINE (<>) #-}++instance Ord k => Monoid (Prio k v) where+    mempty  = NoPrio+    {-# INLINE mempty #-}+    mappend = appendPrio+    {-# INLINE mappend #-}++instance Ord k => Measured (Prio k v) (Entry k v) where+    measure (Entry k v) = Prio k v++-- | Priority queues.+newtype PQueue k v = PQueue (FingerTree (Prio k v) (Entry k v))++instance Ord k => Functor (PQueue k) where+    fmap f (PQueue xs) = PQueue (FT.fmap' (fmap f) xs)++instance Ord k => Foldable (PQueue k) where+    foldMap f q = case minView q of+        Nothing      -> mempty+        Just (v, q') -> f v `mappend` foldMap f q'++instance Ord k => S.Semigroup (PQueue k v) where+  (<>) = union+  {-# INLINE (<>) #-}++instance Ord k => Monoid (PQueue k v) where+  mempty = empty+  {-# INLINE mempty #-}+  mappend = union+  {-# INLINE mappend #-}++-- | /O(1)/. The empty priority queue.+empty :: Ord k => PQueue k v+empty = PQueue FT.empty++-- | /O(1)/. A singleton priority queue.+singleton :: Ord k => k -> v -> PQueue k v+singleton k v = PQueue (FT.singleton (Entry k v))++-- | /O(log n)/. Add a (priority, value) pair to the front of a priority queue.+--+-- * @'insert' k v q = 'union' ('singleton' k v) q@+--+-- If @q@ contains entries with the same priority @k@, 'minView' of+-- @'insert' k v q@ will return them after this one.+insert :: Ord k => k -> v -> PQueue k v -> PQueue k v+insert k v (PQueue q) = PQueue (Entry k v <| q)++-- | /O(log n)/. Add a (priority, value) pair to the back of a priority queue.+--+-- * @'add' k v q = 'union' q ('singleton' k v)@+--+-- If @q@ contains entries with the same priority @k@, 'minView' of+-- @'add' k v q@ will return them before this one.+add :: Ord k => k -> v -> PQueue k v -> PQueue k v+add k v (PQueue q) = PQueue (q |> Entry k v)++-- | /O(log(min(n1,n2)))/. Concatenate two priority queues.+-- 'union' is associative, with identity 'empty'.+--+-- If there are entries with the same priority in both arguments, 'minView'+-- of @'union' xs ys@ will return those from @xs@ before those from @ys@.+union :: Ord k => PQueue k v -> PQueue k v -> PQueue k v+union (PQueue xs) (PQueue ys) = PQueue (xs >< ys)++-- | /O(n)/. Create a priority queue from a finite list of priorities+-- and values.+fromList :: Ord k => [(k, v)] -> PQueue k v+fromList = foldr (uncurry insert) empty++-- | /O(1)/. Is this the empty priority queue?+null :: Ord k => PQueue k v -> Bool+null (PQueue q) = FT.null q++-- | /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.+--+--  * @'minView' 'empty' = 'Nothing'@+--+--  * @'minView' ('singleton' k v) = 'Just' (v, 'empty')@+--+minView :: Ord k => PQueue k v -> Maybe (v, PQueue k v)+minView q = fmap (snd *** id) (minViewWithKey q)++-- | /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.+--+--  * @'minViewWithKey' 'empty' = 'Nothing'@+--+--  * @'minViewWithKey' ('singleton' k v) = 'Just' ((k, v), 'empty')@+--+--  * If @'minViewWithKey' qi = 'Just' ((ki, vi), qi')@ and @k1 <= k2@,+--    then @'minViewWithKey' ('union' q1 q2) = 'Just' ((k1, v1), 'union' q1' q2)@+--+--  * If @'minViewWithKey' qi = 'Just' ((ki, vi), qi')@ and @k2 < k1@,+--    then @'minViewWithKey' ('union' q1 q2) = 'Just' ((k2, v2), 'union' q1 q2')@+--+minViewWithKey :: Ord k => PQueue k v -> Maybe ((k, v), PQueue k v)+minViewWithKey (PQueue q)+  | FT.null q = Nothing+  | otherwise = Just ((k, v), case FT.viewl r of+    _ :< r' -> PQueue (l >< r')+    _       -> error "can't happen")+  where+    Prio k v = measure q+    (l, r) = FT.split (below k) q++below :: Ord k => k -> Prio k v -> Bool+below _ NoPrio      = False+below k (Prio k' _) = k' <= k
+ tests/HaskellWorks/Data/FingerTree/Gen.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE FlexibleContexts #-}++module HaskellWorks.Data.FingerTree.Gen where++import Control.Monad+import HaskellWorks.Data.FingerTree+import Hedgehog++import qualified Hedgehog.Gen             as G+import qualified Hedgehog.Internal.Gen    as G+import qualified Hedgehog.Internal.Shrink as S+import qualified Hedgehog.Range           as R++genList :: MonadGen m => Range Int -> m a -> m [a]+genList range gen =+  G.sized $ \size ->+    (traverse snd =<<) .+    G.ensure (G.atLeast $ R.lowerBound size range) .+    G.shrink S.list $ do+      k <- G.integral_ range+      replicateM k (G.freeze gen)++shrinkFingerTree :: Measured v a => FingerTree v a -> [FingerTree v a]+shrinkFingerTree (Deep _ (One a) Empty (One b)) = [Single a, Single b]+shrinkFingerTree (Deep _ pr m sf) =+    [deep pr' m  sf  | pr' <- shrinkDigit      pr] +++    [deep pr  m' sf  | m'  <- shrinkFingerTree m ] +++    [deep pr  m  sf' | sf' <- shrinkDigit      sf]+shrinkFingerTree (Single x) = []+shrinkFingerTree Empty = []++fingerTree :: (MonadGen m, Measured v a) => m a -> m (FingerTree v a)+fingerTree gen = G.sized $ \size -> genSizedFingerTree size gen++genSizedFingerTree :: (MonadGen m, Measured v a) => Size -> m a -> m (FingerTree v a)+genSizedFingerTree n gen = G.shrink shrinkFingerTree $ case n of+    0 -> return Empty+    1 -> Single <$> gen+    n -> deep <$> (One <$> gen) <*> genSizedFingerTree (n `div` 2) (genSizedNode (n `div` 2) gen) <*> (One <$> gen)++shrinkNode :: Measured v a => Node v a -> [Node v a]+shrinkNode (Node2 _ a b) = []+shrinkNode (Node3 _ a b c) = [node2 a  b, node2 a c, node2 b c]++genSizedNode :: (MonadGen m, Measured v a) => Size -> m a -> m (Node v a)+genSizedNode n gen = G.shrink shrinkNode $ G.choice+    [ node2 <$> gen <*> gen+    , node3 <$> gen <*> gen <*> gen+    ]++shrinkDigit :: Digit a -> [Digit a]+shrinkDigit (One a)         = []+shrinkDigit (Two a b)       = [One a, One b]+shrinkDigit (Three a b c)   = [Two a b, Two a c, Two b c]+shrinkDigit (Four a b c d)  = [Three a b c, Three a b d, Three a c d, Three b c d]
+ tests/HaskellWorks/Data/FingerTreeSpec.hs view
@@ -0,0 +1,211 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module HaskellWorks.Data.FingerTreeSpec (spec) where++import Control.Applicative          (Applicative (..))+import Control.Monad                (ap)+import Data.Foldable                (Foldable (foldMap, foldl, foldr), all, toList)+import Data.Functor                 ((<$>))+import Data.List                    (inits)+import Data.Monoid                  (Monoid (..))+import Data.Traversable             (traverse)+import HaskellWorks.Data.FingerTree+import HaskellWorks.Hspec.Hedgehog+import Hedgehog                     hiding (evalM)+import Prelude                      hiding (null, reverse)+import Test.Hspec++import qualified HaskellWorks.Data.FingerTree.Gen as G+import qualified Hedgehog.Gen                     as G+import qualified Hedgehog.Range                   as R+import qualified Prelude                          as P++{-# ANN module ("HLint: ignore Redundant do"        :: String) #-}+{-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}+{-# ANN module ("HLint: redundant bracket"          :: String) #-}++spec :: Spec+spec = do+  it "foldr" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    foldr (:) [] xs === P.foldr (:) [] (toList xs)+  it "foldl" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    foldl (flip (:)) [] xs === P.foldl (flip (:)) [] (toList xs)+  it "(==)" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    ys <- forAll (G.fingerTree (G.int R.constantBounded))+    (xs == ys) === (toList xs == toList ys)+  it "compare" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    ys <- forAll (G.fingerTree (G.int R.constantBounded))+    compare xs ys === compare (toList xs) (toList ys)+  it "mappend" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    ys <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (mappend xs ys) ~== toList xs ++ toList ys+  it "empty" $ require $ property $ do+    toList' (empty :: Seq Int) === Just []+  it "singletone" $ require $ property $ do+    x <- forAll (G.int R.constantBounded)+    toList' (singleton x) ~== [x]+  it "(<|)" $ require $ property $ do+    x  <- forAll (G.int R.constantBounded)+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (x <| xs) ~== x : toList xs+  it "(|>)" $ require $ property $ do+    x  <- forAll (G.int R.constantBounded)+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (xs |> x) ~== toList xs ++ [x]+  it "(><)" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    ys <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (xs >< ys) ~== toList xs ++ toList ys+  it "fromList" $ require $ property $ do+    xs <- forAll (G.list (R.linear 0 100) (G.int R.constantBounded))+    toList' (fromList xs) ~== xs+  it "null" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    null xs === P.null (toList xs)+  it "viewl" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    case viewl xs of+      EmptyL    -> P.null (toList xs) === True+      x :< xs'  -> do+        valid xs' === True+        toList xs === x : toList xs'+  it "viewr" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    case viewr xs of+      EmptyR    -> P.null (toList xs) === True+      xs' :> x  -> do+        valid xs' === True+        toList xs === toList xs' ++ [x]+  it "split" $ require $ property $ do+    n <- forAll (G.int R.constantBounded)+    let p ys = P.length ys > n+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    toListPair' (split p xs) ~== P.splitAt n (toList xs)+  it "takeUntil" $ require $ property $ do+    n <- forAll (G.int R.constantBounded)+    let p ys = P.length ys > n+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (takeUntil p xs) ~== P.take n (toList xs)+  it "dropUntil" $ require $ property $ do+    n <- forAll (G.int R.constantBounded)+    let p ys = P.length ys > n+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (dropUntil p xs) ~== P.drop n (toList xs)+  it "reverse" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (reverse xs) ~== P.reverse (toList xs)+  it "fmap" $ require $ property $ do+    let f = Just+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (fmap' f xs) ~== map f (toList xs)+  it "fmapWithPos" $ require $ property $ do+    let f = (,)+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    let xs_list = toList xs+    toList' (fmapWithPos f xs) ~== zipWith f (inits xs_list) xs_list+  it "traverse" $ require $ property $ do+    let f x = do+          n <- step+          return (n, x)+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    toList' (evalM (traverse' f xs)) ~== evalM (traverse f (toList xs))+  it "traverseWithPos" $ require $ property $ do+    xs <- forAll (G.fingerTree (G.int R.constantBounded))+    let f xs y = do+          n <- step+          return (xs, n, y)+    let xs_list = toList xs+    toList' (evalM (traverseWithPos f xs)) ~== evalM (traverse (uncurry f) (zip (inits xs_list) xs_list))++infix 4 ~==++(~==) :: (Show a, Eq a) => Maybe a -> a -> PropertyT IO ()+(~==) = maybe (const failure) (===)++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)++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++toList' :: (Eq a, Measured [a] a, Valid a) => Seq a -> Maybe [a]+toList' xs+  | valid xs = Just (toList xs)+  | otherwise = Nothing++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 Int 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 [Int] Int 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]
+ tests/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
− tests/ft-properties.hs
@@ -1,337 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}--- QuickCheck properties for Data.FingerTree--module Main where--import HaskellWorks.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(foldMap, foldl, foldr), 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)