mono-traversable 0.3.0.1 → 0.3.0.2
raw patch · 8 files changed
+809/−22 lines, 8 filesdep ~base
Dependency ranges changed: base
Files
- README.md +22/−0
- mono-traversable.cabal +1/−1
- src/Data/Containers.hs +126/−0
- src/Data/MinLen.hs +8/−0
- src/Data/MonoTraversable.hs +201/−2
- src/Data/NonNull.hs +6/−3
- src/Data/Sequences.hs +432/−16
- test/Spec.hs +13/−0
README.md view
@@ -3,6 +3,9 @@ Type classes for mapping, folding, and traversing monomorphic containers. Contains even more experimental code for abstracting containers and sequences. +A polymorphin container is one such as list which has a type variable `[a]`+A monomorphic container is one such as Text which has a type `Text` that does not expose the underlying characters.+ Adding instances ---------------- @@ -35,6 +38,25 @@ in your code, and your ready to use ```CustomType a``` with the functions defined in this package. **Note**: if your type is as _monomorphic container_ without the proper typeclasses, then you will have to provide an implementation. However, this should be fairly simple, as it can be seen [in the code](https://hackage.haskell.org/package/mono-traversable-0.2.0.0/docs/src/Data-MonoTraversable.html#line-234)+++mono-traversable versuse lens Traversal+---------------------------------------+lens is a huge package with a lot of functionality.+One piece of functionality it exposes is Fold and Traversal which can also be used to deal with monomorphic containers.++You could prefer mono-traversable to using this part of lens because++* There is really no new API to learn. If you know Foldable, you can use MonoFoldable just as easily+* mono-traversable's typeclass based approach means many methods are included in the class but can easily be given specialised optimized implementations+* You don't need to explicitly pass around the Traversal++The last point is also a point of inflexibility and points to a use case where you could prefer using a lens Traversal.+mono-traversable treats ByteString as a sequence of bytes.+If you want to treat it as both bytes and characters, mono-traversable would require a newtype wrapper around ByteString,+whereas a lens traversal would just use a different traversal function.++ [](http://travis-ci.org/snoyberg/mono-traversable)
mono-traversable.cabal view
@@ -1,5 +1,5 @@ name: mono-traversable-version: 0.3.0.1+version: 0.3.0.2 synopsis: Type classes for mapping, folding, and traversing monomorphic containers description: Monomorphic variants of the Functor, Foldable, and Traversable typeclasses. Contains even more experimental code for abstracting containers and sequences. homepage: https://github.com/snoyberg/mono-traversable
src/Data/Containers.hs view
@@ -41,56 +41,89 @@ instance Ord k => SetContainer (Map.Map k v) where type ContainerKey (Map.Map k v) = k member = Map.member+ {-# INLINE member #-} notMember = Map.notMember+ {-# INLINE notMember #-} union = Map.union+ {-# INLINE union #-} difference = Map.difference+ {-# INLINE difference #-} intersection = Map.intersection+ {-# INLINE intersection #-} instance (Eq key, Hashable key) => SetContainer (HashMap.HashMap key value) where type ContainerKey (HashMap.HashMap key value) = key member = HashMap.member+ {-# INLINE member #-} notMember k = not . HashMap.member k+ {-# INLINE notMember #-} union = HashMap.union+ {-# INLINE union #-} difference = HashMap.difference+ {-# INLINE difference #-} intersection = HashMap.intersection+ {-# INLINE intersection #-} instance SetContainer (IntMap.IntMap value) where type ContainerKey (IntMap.IntMap value) = Int member = IntMap.member+ {-# INLINE member #-} notMember = IntMap.notMember+ {-# INLINE notMember #-} union = IntMap.union+ {-# INLINE union #-} difference = IntMap.difference+ {-# INLINE difference #-} intersection = IntMap.intersection+ {-# INLINE intersection #-} instance Ord element => SetContainer (Set.Set element) where type ContainerKey (Set.Set element) = element member = Set.member+ {-# INLINE member #-} notMember = Set.notMember+ {-# INLINE notMember #-} union = Set.union+ {-# INLINE union #-} difference = Set.difference+ {-# INLINE difference #-} intersection = Set.intersection+ {-# INLINE intersection #-} instance (Eq element, Hashable element) => SetContainer (HashSet.HashSet element) where type ContainerKey (HashSet.HashSet element) = element member = HashSet.member+ {-# INLINE member #-} notMember e = not . HashSet.member e+ {-# INLINE notMember #-} union = HashSet.union+ {-# INLINE union #-} difference = HashSet.difference+ {-# INLINE difference #-} intersection = HashSet.intersection+ {-# INLINE intersection #-} instance SetContainer IntSet.IntSet where type ContainerKey IntSet.IntSet = Int member = IntSet.member+ {-# INLINE member #-} notMember = IntSet.notMember+ {-# INLINE notMember #-} union = IntSet.union+ {-# INLINE union #-} difference = IntSet.difference+ {-# INLINE difference #-} intersection = IntSet.intersection+ {-# INLINE intersection #-} instance Eq key => SetContainer [(key, value)] where type ContainerKey [(key, value)] = key member k = List.any ((== k) . fst)+ {-# INLINE member #-} notMember k = not . member k+ {-# INLINE notMember #-} union = List.unionBy ((==) `on` fst)+ {-# INLINE union #-} x `difference` y = loop x where@@ -100,6 +133,7 @@ Nothing -> (k, v) : loop rest Just _ -> loop rest intersection = List.intersectBy ((==) `on` fst)+ {-# INLINE intersection #-} -- | A guaranteed-polymorphic @Map@, which allows for more polymorphic versions -- of functions.@@ -115,21 +149,30 @@ instance Ord key => PolyMap (Map.Map key) where differenceMap = Map.difference+ {-# INLINE differenceMap #-} --differenceWithMap = Map.differenceWith intersectionMap = Map.intersection+ {-# INLINE intersectionMap #-} intersectionWithMap = Map.intersectionWith+ {-# INLINE intersectionWithMap #-} instance (Eq key, Hashable key) => PolyMap (HashMap.HashMap key) where differenceMap = HashMap.difference+ {-# INLINE differenceMap #-} --differenceWithMap = HashMap.differenceWith intersectionMap = HashMap.intersection+ {-# INLINE intersectionMap #-} intersectionWithMap = HashMap.intersectionWith+ {-# INLINE intersectionWithMap #-} instance PolyMap IntMap.IntMap where differenceMap = IntMap.difference+ {-# INLINE differenceMap #-} --differenceWithMap = IntMap.differenceWith intersectionMap = IntMap.intersection+ {-# INLINE intersectionMap #-} intersectionWithMap = IntMap.intersectionWith+ {-# INLINE intersectionWithMap #-} class (MonoTraversable map, SetContainer map) => IsMap map where -- | In some cases, @MapValue@ and @Element@ will be different, e.g., the@@ -322,48 +365,78 @@ instance Ord key => IsMap (Map.Map key value) where type MapValue (Map.Map key value) = value lookup = Map.lookup+ {-# INLINE lookup #-} insertMap = Map.insert+ {-# INLINE insertMap #-} deleteMap = Map.delete+ {-# INLINE deleteMap #-} singletonMap = Map.singleton+ {-# INLINE singletonMap #-} mapFromList = Map.fromList+ {-# INLINE mapFromList #-} mapToList = Map.toList+ {-# INLINE mapToList #-} findWithDefault = Map.findWithDefault+ {-# INLINE findWithDefault #-} insertWith = Map.insertWith+ {-# INLINE insertWith #-} insertWithKey = Map.insertWithKey+ {-# INLINE insertWithKey #-} insertLookupWithKey = Map.insertLookupWithKey+ {-# INLINE insertLookupWithKey #-} adjustMap = Map.adjust+ {-# INLINE adjustMap #-} adjustWithKey = Map.adjustWithKey+ {-# INLINE adjustWithKey #-} updateMap = Map.update+ {-# INLINE updateMap #-} updateWithKey = Map.updateWithKey+ {-# INLINE updateWithKey #-} updateLookupWithKey = Map.updateLookupWithKey+ {-# INLINE updateLookupWithKey #-} alterMap = Map.alter+ {-# INLINE alterMap #-} unionWith = Map.unionWith+ {-# INLINE unionWith #-} unionWithKey = Map.unionWithKey+ {-# INLINE unionWithKey #-} unionsWith = Map.unionsWith+ {-# INLINE unionsWith #-} mapWithKey = Map.mapWithKey+ {-# INLINE mapWithKey #-} mapKeysWith = Map.mapKeysWith+ {-# INLINE mapKeysWith #-} instance (Eq key, Hashable key) => IsMap (HashMap.HashMap key value) where type MapValue (HashMap.HashMap key value) = value lookup = HashMap.lookup+ {-# INLINE lookup #-} insertMap = HashMap.insert+ {-# INLINE insertMap #-} deleteMap = HashMap.delete+ {-# INLINE deleteMap #-} singletonMap = HashMap.singleton+ {-# INLINE singletonMap #-} mapFromList = HashMap.fromList+ {-# INLINE mapFromList #-} mapToList = HashMap.toList+ {-# INLINE mapToList #-} --findWithDefault = HashMap.findWithDefault insertWith = HashMap.insertWith+ {-# INLINE insertWith #-} --insertWithKey = HashMap.insertWithKey --insertLookupWithKey = HashMap.insertLookupWithKey adjustMap = HashMap.adjust+ {-# INLINE adjustMap #-} --adjustWithKey = HashMap.adjustWithKey --updateMap = HashMap.update --updateWithKey = HashMap.updateWithKey --updateLookupWithKey = HashMap.updateLookupWithKey --alterMap = HashMap.alter unionWith = HashMap.unionWith+ {-# INLINE unionWith #-} --unionWithKey = HashMap.unionWithKey --unionsWith = HashMap.unionsWith --mapWithKey = HashMap.mapWithKey@@ -372,38 +445,64 @@ instance IsMap (IntMap.IntMap value) where type MapValue (IntMap.IntMap value) = value lookup = IntMap.lookup+ {-# INLINE lookup #-} insertMap = IntMap.insert+ {-# INLINE insertMap #-} deleteMap = IntMap.delete+ {-# INLINE deleteMap #-} singletonMap = IntMap.singleton+ {-# INLINE singletonMap #-} mapFromList = IntMap.fromList+ {-# INLINE mapFromList #-} mapToList = IntMap.toList+ {-# INLINE mapToList #-} findWithDefault = IntMap.findWithDefault+ {-# INLINE findWithDefault #-} insertWith = IntMap.insertWith+ {-# INLINE insertWith #-} insertWithKey = IntMap.insertWithKey+ {-# INLINE insertWithKey #-} insertLookupWithKey = IntMap.insertLookupWithKey+ {-# INLINE insertLookupWithKey #-} adjustMap = IntMap.adjust+ {-# INLINE adjustMap #-} adjustWithKey = IntMap.adjustWithKey+ {-# INLINE adjustWithKey #-} updateMap = IntMap.update+ {-# INLINE updateMap #-} updateWithKey = IntMap.updateWithKey+ {-# INLINE updateWithKey #-} --updateLookupWithKey = IntMap.updateLookupWithKey alterMap = IntMap.alter+ {-# INLINE alterMap #-} unionWith = IntMap.unionWith+ {-# INLINE unionWith #-} unionWithKey = IntMap.unionWithKey+ {-# INLINE unionWithKey #-} unionsWith = IntMap.unionsWith+ {-# INLINE unionsWith #-} mapWithKey = IntMap.mapWithKey+ {-# INLINE mapWithKey #-} #if MIN_VERSION_containers(0, 5, 0) mapKeysWith = IntMap.mapKeysWith+ {-# INLINE mapKeysWith #-} #endif instance Eq key => IsMap [(key, value)] where type MapValue [(key, value)] = value lookup = List.lookup+ {-# INLINE lookup #-} insertMap k v = ((k, v):) . deleteMap k+ {-# INLINE insertMap #-} deleteMap k = List.filter ((/= k) . fst)+ {-# INLINE deleteMap #-} singletonMap k v = [(k, v)]+ {-# INLINE singletonMap #-} mapFromList = id+ {-# INLINE mapFromList #-} mapToList = id+ {-# INLINE mapToList #-} class (SetContainer set, Element set ~ ContainerKey set) => IsSet set where insertSet :: Element set -> set -> set@@ -414,24 +513,39 @@ instance Ord element => IsSet (Set.Set element) where insertSet = Set.insert+ {-# INLINE insertSet #-} deleteSet = Set.delete+ {-# INLINE deleteSet #-} singletonSet = Set.singleton+ {-# INLINE singletonSet #-} setFromList = Set.fromList+ {-# INLINE setFromList #-} setToList = Set.toList+ {-# INLINE setToList #-} instance (Eq element, Hashable element) => IsSet (HashSet.HashSet element) where insertSet = HashSet.insert+ {-# INLINE insertSet #-} deleteSet = HashSet.delete+ {-# INLINE deleteSet #-} singletonSet = HashSet.singleton+ {-# INLINE singletonSet #-} setFromList = HashSet.fromList+ {-# INLINE setFromList #-} setToList = HashSet.toList+ {-# INLINE setToList #-} instance IsSet IntSet.IntSet where insertSet = IntSet.insert+ {-# INLINE insertSet #-} deleteSet = IntSet.delete+ {-# INLINE deleteSet #-} singletonSet = IntSet.singleton+ {-# INLINE singletonSet #-} setFromList = IntSet.fromList+ {-# INLINE setFromList #-} setToList = IntSet.toList+ {-# INLINE setToList #-} -- | zip operations on MonoFunctors.@@ -445,15 +559,27 @@ ozip = ByteString.zip ounzip = ByteString.unzip ozipWith f xs = ByteString.pack . ByteString.zipWith f xs+ {-# INLINE ozip #-}+ {-# INLINE ounzip #-}+ {-# INLINE ozipWith #-} instance MonoZip LByteString.ByteString where ozip = LByteString.zip ounzip = LByteString.unzip ozipWith f xs = LByteString.pack . LByteString.zipWith f xs+ {-# INLINE ozip #-}+ {-# INLINE ounzip #-}+ {-# INLINE ozipWith #-} instance MonoZip Text.Text where ozip = Text.zip ounzip = (Text.pack *** Text.pack) . List.unzip ozipWith = Text.zipWith+ {-# INLINE ozip #-}+ {-# INLINE ounzip #-}+ {-# INLINE ozipWith #-} instance MonoZip LText.Text where ozip = LText.zip ounzip = (LText.pack *** LText.pack) . List.unzip ozipWith = LText.zipWith+ {-# INLINE ozip #-}+ {-# INLINE ounzip #-}+ {-# INLINE ozipWith #-}
src/Data/MinLen.hs view
@@ -68,24 +68,32 @@ mlcons :: IsSequence seq => Element seq -> MinLen nat seq -> MinLen (Succ nat) seq mlcons e (MinLen seq) = MinLen (cons e seq)+{-# INLINE mlcons #-} mlappend :: IsSequence seq => MinLen x seq -> MinLen y seq -> MinLen (AddNat x y) seq mlappend (MinLen x) (MinLen y) = MinLen (x `mappend` y)+{-# INLINE mlappend #-} head :: MonoTraversable mono => MinLen (Succ nat) mono -> Element mono head = headEx . unMinLen+{-# INLINE head #-} last :: MonoTraversable mono => MinLen (Succ nat) mono -> Element mono last = lastEx . unMinLen+{-# INLINE last #-} tail :: IsSequence seq => MinLen (Succ nat) seq -> MinLen nat seq tail = MinLen . tailEx . unMinLen+{-# INLINE tail #-} init :: IsSequence seq => MinLen (Succ nat) seq -> MinLen nat seq init = MinLen . initEx . unMinLen+{-# INLINE init #-} instance GrowingAppend mono => Semigroup (MinLen nat mono) where MinLen x <> MinLen y = MinLen (x <> y)+ {-# INLINE (<>) #-} mlunion :: GrowingAppend mono => MinLen x mono -> MinLen y mono -> MinLen (MaxNat x y) mono mlunion (MinLen x) (MinLen y) = MinLen (x <> y)+{-# INLINE mlunion #-}
src/Data/MonoTraversable.hs view
@@ -139,15 +139,20 @@ omap :: (Element mono -> Element mono) -> mono -> mono default omap :: (Functor f, Element (f a) ~ a, f a ~ mono) => (a -> a) -> f a -> f a omap = fmap+ {-# INLINE omap #-} instance MonoFunctor S.ByteString where omap = S.map+ {-# INLINE omap #-} instance MonoFunctor L.ByteString where omap = L.map+ {-# INLINE omap #-} instance MonoFunctor T.Text where omap = T.map+ {-# INLINE omap #-} instance MonoFunctor TL.Text where omap = TL.map+ {-# INLINE omap #-} instance MonoFunctor [a] instance MonoFunctor (IO a) instance MonoFunctor (ZipList a)@@ -189,51 +194,66 @@ instance Functor f => MonoFunctor (Static f a b) instance U.Unbox a => MonoFunctor (U.Vector a) where omap = U.map+ {-# INLINE omap #-} instance VS.Storable a => MonoFunctor (VS.Vector a) where omap = VS.map+ {-# INLINE omap #-} class MonoFoldable mono where ofoldMap :: Monoid m => (Element mono -> m) -> mono -> m default ofoldMap :: (t a ~ mono, a ~ Element (t a), F.Foldable t, Monoid m) => (Element mono -> m) -> mono -> m ofoldMap = F.foldMap+ {-# INLINE ofoldMap #-} ofoldr :: (Element mono -> b -> b) -> b -> mono -> b default ofoldr :: (t a ~ mono, a ~ Element (t a), F.Foldable t) => (Element mono -> b -> b) -> b -> mono -> b ofoldr = F.foldr+ {-# INLINE ofoldr #-} ofoldl' :: (a -> Element mono -> a) -> a -> mono -> a default ofoldl' :: (t b ~ mono, b ~ Element (t b), F.Foldable t) => (a -> Element mono -> a) -> a -> mono -> a ofoldl' = F.foldl'+ {-# INLINE ofoldl' #-} otoList :: mono -> [Element mono] otoList t = build (\ mono n -> ofoldr mono n t)+ {-# INLINE otoList #-} oall :: (Element mono -> Bool) -> mono -> Bool oall f = getAll . ofoldMap (All . f)+ {-# INLINE oall #-} oany :: (Element mono -> Bool) -> mono -> Bool oany f = getAny . ofoldMap (Any . f)+ {-# INLINE oany #-} onull :: mono -> Bool onull = oall (const False)+ {-# INLINE onull #-} olength :: mono -> Int olength = ofoldl' (\i _ -> i + 1) 0+ {-# INLINE olength #-} olength64 :: mono -> Int64 olength64 = ofoldl' (\i _ -> i + 1) 0+ {-# INLINE olength64 #-} ocompareLength :: Integral i => mono -> i -> Ordering ocompareLength c0 i0 = olength c0 `compare` fromIntegral i0 -- FIXME more efficient implementation+ {-# INLINE ocompareLength #-} otraverse_ :: (MonoFoldable mono, Applicative f) => (Element mono -> f b) -> mono -> f () otraverse_ f = ofoldr ((*>) . f) (pure ())+ {-# INLINE otraverse_ #-} ofor_ :: (MonoFoldable mono, Applicative f) => mono -> (Element mono -> f b) -> f () ofor_ = flip otraverse_+ {-# INLINE ofor_ #-} omapM_ :: (MonoFoldable mono, Monad m) => (Element mono -> m b) -> mono -> m () omapM_ f = ofoldr ((>>) . f) (return ())+ {-# INLINE omapM_ #-} oforM_ :: (MonoFoldable mono, Monad m) => mono -> (Element mono -> m b) -> m () oforM_ = flip omapM_@@ -242,6 +262,7 @@ ofoldlM :: (MonoFoldable mono, Monad m) => (a -> Element mono -> m a) -> a -> mono -> m a ofoldlM f z0 xs = ofoldr f' return xs z0 where f' x k z = f z x >>= k+ {-# INLINE ofoldlM #-} -- | Note: this is a partial function. On an empty @MonoFoldable@, it will -- throw an exception. See "Data.NonNull" for a total version of this@@ -257,6 +278,7 @@ default ofoldr1Ex :: (t a ~ mono, a ~ Element (t a), F.Foldable t) => (a -> a -> a) -> mono -> a ofoldr1Ex = F.foldr1+ {-# INLINE ofoldr1Ex #-} -- | Note: this is a partial function. On an empty @MonoFoldable@, it will -- throw an exception. See "Data.NonNull" for a total version of this@@ -265,18 +287,23 @@ default ofoldl1Ex' :: (t a ~ mono, a ~ Element (t a), F.Foldable t) => (a -> a -> a) -> mono -> a ofoldl1Ex' = F.foldl1+ {-# INLINE ofoldl1Ex' #-} headEx :: mono -> Element mono headEx = ofoldr1Ex const+ {-# INLINE headEx #-} lastEx :: mono -> Element mono lastEx = ofoldl1Ex' (flip const)+ {-# INLINE lastEx #-} unsafeHead :: mono -> Element mono unsafeHead = headEx+ {-# INLINE unsafeHead #-} unsafeLast :: mono -> Element mono unsafeLast = lastEx+ {-# INLINE unsafeLast #-} instance MonoFoldable S.ByteString where ofoldMap f = ofoldr (mappend . f) mempty@@ -297,12 +324,25 @@ _ <- f (Unsafe.inlinePerformIO (peek ptr)) loop (ptr `plusPtr` 1) loop start- {-# INLINE omapM_ #-} ofoldr1Ex = S.foldr1 ofoldl1Ex' = S.foldl1' headEx = S.head lastEx = S.last unsafeHead = SU.unsafeHead+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} instance MonoFoldable L.ByteString where ofoldMap f = ofoldr (mappend . f) mempty ofoldr = L.foldr@@ -313,11 +353,24 @@ onull = L.null olength64 = L.length omapM_ f = omapM_ (omapM_ f) . L.toChunks- {-# INLINE omapM_ #-} ofoldr1Ex = L.foldr1 ofoldl1Ex' = L.foldl1' headEx = L.head lastEx = L.last+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength64 #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} instance MonoFoldable T.Text where ofoldMap f = ofoldr (mappend . f) mempty ofoldr = T.foldr@@ -331,6 +384,20 @@ ofoldl1Ex' = T.foldl1' headEx = T.head lastEx = T.last+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} instance MonoFoldable TL.Text where ofoldMap f = ofoldr (mappend . f) mempty ofoldr = TL.foldr@@ -344,6 +411,20 @@ ofoldl1Ex' = TL.foldl1' headEx = TL.head lastEx = TL.last+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} instance MonoFoldable IntSet where ofoldMap f = ofoldr (mappend . f) mempty ofoldr = IntSet.foldr@@ -353,6 +434,20 @@ olength = IntSet.size ofoldr1Ex f = ofoldr1Ex f . IntSet.toList ofoldl1Ex' f = ofoldl1Ex' f . IntSet.toList+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} instance MonoFoldable [a] where otoList = id {-# INLINE otoList #-}@@ -364,6 +459,8 @@ instance MonoFoldable (Seq a) where headEx = flip Seq.index 1 lastEx xs = Seq.index xs (Seq.length xs - 1)+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-} instance MonoFoldable (ViewL a) instance MonoFoldable (ViewR a) instance MonoFoldable (IntMap a)@@ -386,6 +483,20 @@ lastEx = V.last unsafeHead = V.unsafeHead unsafeLast = V.unsafeLast+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} instance MonoFoldable (Set e) instance MonoFoldable (HashSet e) instance U.Unbox a => MonoFoldable (U.Vector a) where@@ -403,6 +514,20 @@ lastEx = U.last unsafeHead = U.unsafeHead unsafeLast = U.unsafeLast+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} instance VS.Storable a => MonoFoldable (VS.Vector a) where ofoldMap f = ofoldr (mappend . f) mempty ofoldr = VS.foldr@@ -418,6 +543,20 @@ lastEx = VS.last unsafeHead = VS.unsafeHead unsafeLast = VS.unsafeLast+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} instance MonoFoldable (Either a b) where ofoldMap f = ofoldr (mappend . f) mempty ofoldr f b (Right a) = f a b@@ -438,26 +577,44 @@ ofoldr1Ex _ (Right x) = x ofoldl1Ex' _ (Left _) = Prelude.error "ofoldl1Ex' on Either" ofoldl1Ex' _ (Right x) = x+ {-# INLINE ofoldMap #-}+ {-# INLINE ofoldr #-}+ {-# INLINE ofoldl' #-}+ {-# INLINE otoList #-}+ {-# INLINE oall #-}+ {-# INLINE oany #-}+ {-# INLINE onull #-}+ {-# INLINE olength #-}+ {-# INLINE omapM_ #-}+ {-# INLINE ofoldr1Ex #-}+ {-# INLINE ofoldl1Ex' #-}+ {-# INLINE headEx #-}+ {-# INLINE lastEx #-}+ {-# INLINE unsafeHead #-} -- | like Data.List.head, but not partial headMay :: MonoFoldable mono => mono -> Maybe (Element mono) headMay mono | onull mono = Nothing | otherwise = Just (headEx mono)+{-# INLINE headMay #-} -- | like Data.List.last, but not partial lastMay :: MonoFoldable mono => mono -> Maybe (Element mono) lastMay mono | onull mono = Nothing | otherwise = Just (lastEx mono)+{-# INLINE lastMay #-} -- | The 'sum' function computes the sum of the numbers of a structure. osum :: (MonoFoldable mono, Num (Element mono)) => mono -> Element mono osum = getSum . ofoldMap Sum+{-# INLINE osum #-} -- | The 'product' function computes the product of the numbers of a structure. oproduct :: (MonoFoldable mono, Num (Element mono)) => mono -> Element mono oproduct = Data.Monoid.getProduct . ofoldMap Data.Monoid.Product+{-# INLINE oproduct #-} class (MonoFoldable mono, Monoid mono) => MonoFoldableMonoid mono where -- FIXME is this really just MonoMonad? oconcatMap :: (Element mono -> mono) -> mono -> mono@@ -465,18 +622,23 @@ instance (MonoFoldable (t a), Monoid (t a)) => MonoFoldableMonoid (t a) -- FIXME instance MonoFoldableMonoid S.ByteString where oconcatMap = S.concatMap+ {-# INLINE oconcatMap #-} instance MonoFoldableMonoid L.ByteString where oconcatMap = L.concatMap+ {-# INLINE oconcatMap #-} instance MonoFoldableMonoid T.Text where oconcatMap = T.concatMap+ {-# INLINE oconcatMap #-} instance MonoFoldableMonoid TL.Text where oconcatMap = TL.concatMap+ {-# INLINE oconcatMap #-} -- | A typeclass for @MonoFoldable@s containing elements which are an instance -- of @Ord@. class (MonoFoldable mono, Ord (Element mono)) => MonoFoldableOrd mono where maximumEx :: mono -> Element mono maximumEx = maximumByEx compare+ {-# INLINE maximumEx #-} maximumByEx :: (Element mono -> Element mono -> Ordering) -> mono -> Element mono maximumByEx f =@@ -486,9 +648,11 @@ case f x y of LT -> y _ -> x+ {-# INLINE maximumByEx #-} minimumEx :: mono -> Element mono minimumEx = minimumByEx compare+ {-# INLINE minimumEx #-} minimumByEx :: (Element mono -> Element mono -> Ordering) -> mono -> Element mono minimumByEx f =@@ -498,6 +662,7 @@ case f x y of GT -> y _ -> x+ {-# INLINE minimumByEx #-} instance MonoFoldableOrd S.ByteString where maximumEx = S.maximum@@ -537,6 +702,10 @@ maximumByEx = V.maximumBy minimumEx = V.minimum minimumByEx = V.minimumBy+ {-# INLINE maximumEx #-}+ {-# INLINE maximumByEx #-}+ {-# INLINE minimumEx #-}+ {-# INLINE minimumByEx #-} instance Ord e => MonoFoldableOrd (Set e) instance Ord e => MonoFoldableOrd (HashSet e) instance (U.Unbox a, Ord a) => MonoFoldableOrd (U.Vector a) where@@ -544,17 +713,26 @@ maximumByEx = U.maximumBy minimumEx = U.minimum minimumByEx = U.minimumBy+ {-# INLINE maximumEx #-}+ {-# INLINE maximumByEx #-}+ {-# INLINE minimumEx #-}+ {-# INLINE minimumByEx #-} instance (Ord a, VS.Storable a) => MonoFoldableOrd (VS.Vector a) where maximumEx = VS.maximum maximumByEx = VS.maximumBy minimumEx = VS.minimum minimumByEx = VS.minimumBy+ {-# INLINE maximumEx #-}+ {-# INLINE maximumByEx #-}+ {-# INLINE minimumEx #-}+ {-# INLINE minimumByEx #-} instance Ord b => MonoFoldableOrd (Either a b) where maximumMay :: MonoFoldableOrd mono => mono -> Maybe (Element mono) maximumMay mono | onull mono = Nothing | otherwise = Just (maximumEx mono)+{-# INLINE maximumMay #-} maximumByMay :: MonoFoldableOrd mono => (Element mono -> Element mono -> Ordering)@@ -563,11 +741,13 @@ maximumByMay f mono | onull mono = Nothing | otherwise = Just (maximumByEx f mono)+{-# INLINE maximumByMay #-} minimumMay :: MonoFoldableOrd mono => mono -> Maybe (Element mono) minimumMay mono | onull mono = Nothing | otherwise = Just (minimumEx mono)+{-# INLINE minimumMay #-} minimumByMay :: MonoFoldableOrd mono => (Element mono -> Element mono -> Ordering)@@ -576,6 +756,7 @@ minimumByMay f mono | onull mono = Nothing | otherwise = Just (minimumByEx f mono)+{-# INLINE minimumByMay #-} class (MonoFunctor mono, MonoFoldable mono) => MonoTraversable mono where otraverse :: Applicative f => (Element mono -> f (Element mono)) -> mono -> f mono@@ -584,18 +765,28 @@ omapM :: Monad m => (Element mono -> m (Element mono)) -> mono -> m mono default omapM :: (Traversable t, mono ~ t a, a ~ Element mono, Monad m) => (Element mono -> m (Element mono)) -> mono -> m mono omapM = mapM+ {-# INLINE otraverse #-}+ {-# INLINE omapM #-} instance MonoTraversable S.ByteString where otraverse f = fmap S.pack . traverse f . S.unpack omapM f = liftM S.pack . mapM f . S.unpack+ {-# INLINE otraverse #-}+ {-# INLINE omapM #-} instance MonoTraversable L.ByteString where otraverse f = fmap L.pack . traverse f . L.unpack omapM f = liftM L.pack . mapM f . L.unpack+ {-# INLINE otraverse #-}+ {-# INLINE omapM #-} instance MonoTraversable T.Text where otraverse f = fmap T.pack . traverse f . T.unpack omapM f = liftM T.pack . mapM f . T.unpack+ {-# INLINE otraverse #-}+ {-# INLINE omapM #-} instance MonoTraversable TL.Text where otraverse f = fmap TL.pack . traverse f . TL.unpack omapM f = liftM TL.pack . mapM f . TL.unpack+ {-# INLINE otraverse #-}+ {-# INLINE omapM #-} instance MonoTraversable [a] instance MonoTraversable (Maybe a) instance MonoTraversable (Tree a)@@ -612,17 +803,25 @@ instance U.Unbox a => MonoTraversable (U.Vector a) where otraverse f = fmap U.fromList . traverse f . U.toList omapM = U.mapM+ {-# INLINE otraverse #-}+ {-# INLINE omapM #-} instance VS.Storable a => MonoTraversable (VS.Vector a) where otraverse f = fmap VS.fromList . traverse f . VS.toList omapM = VS.mapM+ {-# INLINE otraverse #-}+ {-# INLINE omapM #-} instance MonoTraversable (Either a b) where otraverse _ (Left a) = pure (Left a) otraverse f (Right b) = fmap Right (f b) omapM _ (Left a) = return (Left a) omapM f (Right b) = liftM Right (f b)+ {-# INLINE otraverse #-}+ {-# INLINE omapM #-} ofor :: (MonoTraversable mono, Applicative f) => mono -> (Element mono -> f (Element mono)) -> f mono ofor = flip otraverse+{-# INLINE ofor #-} oforM :: (MonoTraversable mono, Monad f) => mono -> (Element mono -> f (Element mono)) -> f mono oforM = flip omapM+{-# INLINE oforM #-}
src/Data/NonNull.hs view
@@ -8,10 +8,10 @@ -- | Warning, this is Experimental! -- -- Data.NonNull attempts to extend the concepts from--- 'Data.List.NonEmpty' to any 'MonoFoldable'.+-- "Data.List.NonEmpty" to any 'MonoFoldable'. -- -- 'NonNull' is a typeclass for a container with 1 or more elements.--- 'Data.List.NonEmpty' and 'NotEmpty a' are members of the typeclass+-- "Data.List.NonEmpty" and 'NotEmpty a' are members of the typeclass module Data.NonNull ( NonNull(..) , fromNonEmpty@@ -46,6 +46,7 @@ import qualified Data.Monoid as Monoid import Data.Data import qualified Data.List.NonEmpty as NE+import Control.Monad (liftM) data NullError = NullError String deriving (Show, Typeable) instance Exception NullError@@ -183,7 +184,9 @@ type instance Element (NotEmpty seq) = Element seq deriving instance MonoFunctor seq => MonoFunctor (NotEmpty seq) deriving instance MonoFoldable seq => MonoFoldable (NotEmpty seq)-deriving instance MonoTraversable seq => MonoTraversable (NotEmpty seq)+instance MonoTraversable seq => MonoTraversable (NotEmpty seq) where+ otraverse f = fmap NotEmpty . otraverse f . fromNotEmpty+ omapM f = liftM NotEmpty . omapM f . fromNotEmpty -- | Helper functions for type inferences. --
src/Data/Sequences.hs view
@@ -18,7 +18,7 @@ import qualified Data.Text as T import qualified Data.Text.Lazy as TL import Control.Category-import Control.Arrow ((***), second)+import Control.Arrow ((***), first, second) import Control.Monad (liftM) import qualified Data.Sequence as Seq import qualified Data.Vector as V@@ -82,7 +82,7 @@ dropWhile :: (Element seq -> Bool) -> seq -> seq dropWhile f = fromList . List.dropWhile f . otoList- + takeWhile :: (Element seq -> Bool) -> seq -> seq takeWhile f = fromList . List.takeWhile f . otoList @@ -106,15 +106,12 @@ partition :: (Element seq -> Bool) -> seq -> (seq, seq) partition f = (fromList *** fromList) . List.partition f . otoList- + uncons :: seq -> Maybe (Element seq, seq) uncons = fmap (second fromList) . uncons . otoList unsnoc :: seq -> Maybe (seq, Element seq)- unsnoc seq =- case reverse (otoList seq) of- [] -> Nothing- x:xs -> Just (fromList (reverse xs), x)+ unsnoc = fmap (first fromList) . unsnoc . otoList filter :: (Element seq -> Bool) -> seq -> seq filter f = fromList . List.filter f . otoList@@ -133,7 +130,7 @@ groupBy :: (Element seq -> Element seq -> Bool) -> seq -> [seq] groupBy f = fmap fromList . List.groupBy f . otoList - -- | Similar to standard 'groupBy', but operates on the whole collection, + -- | Similar to standard 'groupBy', but operates on the whole collection, -- not just the consecutive items. groupAllOn :: Eq b => (Element seq -> b) -> seq -> [seq] groupAllOn f = fmap fromList . groupAllOn f . otoList@@ -155,39 +152,70 @@ unsafeInit :: seq -> seq unsafeInit = initEx+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} defaultFind :: MonoFoldable seq => (Element seq -> Bool) -> seq -> Maybe (Element seq) defaultFind f = List.find f . otoList+{-# INLINE defaultFind #-} defaultIntersperse :: IsSequence seq => Element seq -> seq -> seq defaultIntersperse e = fromList . List.intersperse e . otoList+{-# INLINE defaultIntersperse #-} defaultReverse :: IsSequence seq => seq -> seq defaultReverse = fromList . List.reverse . otoList+{-# INLINE defaultReverse #-} defaultSortBy :: IsSequence seq => (Element seq -> Element seq -> Ordering) -> seq -> seq defaultSortBy f = fromList . List.sortBy f . otoList+{-# INLINE defaultSortBy #-} defaultCons :: IsSequence seq => Element seq -> seq -> seq defaultCons e = fromList . (e:) . otoList+{-# INLINE defaultCons #-} defaultSnoc :: IsSequence seq => seq -> Element seq -> seq defaultSnoc seq e = fromList (otoList seq List.++ [e])-+{-# INLINE defaultSnoc #-} -- | like Data.List.tail, but an input of @mempty@ returns @mempty@ tailDef :: IsSequence seq => seq -> seq tailDef xs = case uncons xs of Nothing -> mempty Just tuple -> snd tuple+{-# INLINE tailDef #-} -- | like Data.List.init, but an input of @mempty@ returns @mempty@ initDef :: IsSequence seq => seq -> seq initDef xs = case unsnoc xs of Nothing -> mempty Just tuple -> fst tuple--+{-# INLINE initDef #-} instance SemiSequence [a] where type Index [a] = Int@@ -198,10 +226,16 @@ sortBy = List.sortBy cons = (:) snoc = defaultSnoc+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance IsSequence [a] where fromList = id- {-# INLINE fromList #-} filter = List.filter filterM = Control.Monad.filterM break = List.break@@ -213,6 +247,12 @@ drop = List.drop uncons [] = Nothing uncons (x:xs) = Just (x, xs)+ unsnoc [] = Nothing+ unsnoc (x0:xs0) =+ Just (loop id x0 xs0)+ where+ loop front x [] = (front [], x)+ loop front x (y:z) = loop (front . (x:)) y z partition = List.partition replicate = List.replicate replicateM = Control.Monad.replicateM@@ -222,6 +262,32 @@ where (matches, nonMatches) = partition ((== f head) . f) tail groupAllOn _ [] = []+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} instance SemiSequence (NE.NonEmpty a) where type Index (NE.NonEmpty a) = Int@@ -233,6 +299,13 @@ cons = NE.cons snoc xs x = NE.fromList $ flip snoc x $ NE.toList xs sortBy f = NE.fromList . List.sortBy f . NE.toList+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance SemiSequence S.ByteString where type Index S.ByteString = Int@@ -243,6 +316,13 @@ cons = S.cons snoc = S.snoc sortBy = defaultSortBy+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance IsSequence S.ByteString where fromList = S.pack@@ -266,6 +346,32 @@ tailEx = S.tail initEx = S.init unsafeTail = SU.unsafeTail+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} instance SemiSequence T.Text where type Index T.Text = Int@@ -276,6 +382,13 @@ cons = T.cons snoc = T.snoc sortBy = defaultSortBy+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance IsSequence T.Text where fromList = T.pack@@ -296,6 +409,32 @@ groupBy = T.groupBy tailEx = T.tail initEx = T.init+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} instance SemiSequence L.ByteString where type Index L.ByteString = Int64@@ -306,6 +445,13 @@ cons = L.cons snoc = L.snoc sortBy = defaultSortBy+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance IsSequence L.ByteString where fromList = L.pack@@ -326,6 +472,32 @@ groupBy = L.groupBy tailEx = L.tail initEx = L.init+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} instance SemiSequence TL.Text where type Index TL.Text = Int64@@ -336,6 +508,13 @@ cons = TL.cons snoc = TL.snoc sortBy = defaultSortBy+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance IsSequence TL.Text where fromList = TL.pack@@ -356,6 +535,32 @@ groupBy = TL.groupBy tailEx = TL.tail initEx = TL.init+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} instance SemiSequence (Seq.Seq a) where type Index (Seq.Seq a) = Int@@ -367,6 +572,13 @@ intersperse = defaultIntersperse find = defaultFind+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance IsSequence (Seq.Seq a) where fromList = Seq.fromList@@ -393,6 +605,32 @@ --groupBy = Seq.groupBy tailEx = Seq.drop 1 initEx xs = Seq.take (Seq.length xs - 1) xs+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} instance SemiSequence (V.Vector a) where type Index (V.Vector a) = Int@@ -404,6 +642,13 @@ sortBy = defaultSortBy intersperse = defaultIntersperse+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance IsSequence (V.Vector a) where fromList = V.fromList@@ -432,6 +677,32 @@ initEx = V.init unsafeTail = V.unsafeTail unsafeInit = V.unsafeInit+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} instance U.Unbox a => SemiSequence (U.Vector a) where type Index (U.Vector a) = Int@@ -443,6 +714,13 @@ cons = U.cons snoc = U.snoc sortBy = defaultSortBy+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance U.Unbox a => IsSequence (U.Vector a) where fromList = U.fromList@@ -471,6 +749,32 @@ initEx = U.init unsafeTail = U.unsafeTail unsafeInit = U.unsafeInit+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} instance VS.Storable a => SemiSequence (VS.Vector a) where type Index (VS.Vector a) = Int@@ -482,6 +786,13 @@ intersperse = defaultIntersperse sortBy = defaultSortBy+ {-# INLINE singleton #-}+ {-# INLINE intersperse #-}+ {-# INLINE reverse #-}+ {-# INLINE find #-}+ {-# INLINE sortBy #-}+ {-# INLINE cons #-}+ {-# INLINE snoc #-} instance VS.Storable a => IsSequence (VS.Vector a) where fromList = VS.fromList@@ -510,14 +821,40 @@ initEx = VS.init unsafeTail = VS.unsafeTail unsafeInit = VS.unsafeInit+ {-# INLINE fromList #-}+ {-# INLINE break #-}+ {-# INLINE span #-}+ {-# INLINE dropWhile #-}+ {-# INLINE takeWhile #-}+ {-# INLINE splitAt #-}+ {-# INLINE unsafeSplitAt #-}+ {-# INLINE take #-}+ {-# INLINE unsafeTake #-}+ {-# INLINE drop #-}+ {-# INLINE unsafeDrop #-}+ {-# INLINE partition #-}+ {-# INLINE uncons #-}+ {-# INLINE unsnoc #-}+ {-# INLINE filter #-}+ {-# INLINE filterM #-}+ {-# INLINE replicate #-}+ {-# INLINE replicateM #-}+ {-# INLINE groupBy #-}+ {-# INLINE groupAllOn #-}+ {-# INLINE subsequences #-}+ {-# INLINE permutations #-}+ {-# INLINE tailEx #-}+ {-# INLINE initEx #-}+ {-# INLINE unsafeTail #-}+ {-# INLINE unsafeInit #-} class (IsSequence seq, Eq (Element seq)) => EqSequence seq where stripPrefix :: seq -> seq -> Maybe seq stripPrefix x y = fmap fromList (otoList x `stripPrefix` otoList y)- + isPrefixOf :: seq -> seq -> Bool isPrefixOf x y = otoList x `isPrefixOf` otoList y- + stripSuffix :: seq -> seq -> Maybe seq stripSuffix x y = fmap fromList (otoList x `stripSuffix` otoList y) @@ -529,8 +866,8 @@ group :: seq -> [seq] group = groupBy (==)- - -- | Similar to standard 'group', but operates on the whole collection, ++ -- | Similar to standard 'group', but operates on the whole collection, -- not just the consecutive items. groupAll :: seq -> [seq] groupAll = groupAllOn id@@ -540,6 +877,15 @@ notElem :: Element seq -> seq -> Bool notElem e = List.notElem e . otoList+ {-# INLINE stripPrefix #-}+ {-# INLINE isPrefixOf #-}+ {-# INLINE stripSuffix #-}+ {-# INLINE isSuffixOf #-}+ {-# INLINE isInfixOf #-}+ {-# INLINE group #-}+ {-# INLINE groupAll #-}+ {-# INLINE elem #-}+ {-# INLINE notElem #-} instance Eq a => EqSequence [a] where stripPrefix = List.stripPrefix@@ -550,6 +896,15 @@ group = List.group elem = List.elem notElem = List.notElem+ {-# INLINE stripPrefix #-}+ {-# INLINE isPrefixOf #-}+ {-# INLINE stripSuffix #-}+ {-# INLINE isSuffixOf #-}+ {-# INLINE isInfixOf #-}+ {-# INLINE group #-}+ {-# INLINE groupAll #-}+ {-# INLINE elem #-}+ {-# INLINE notElem #-} instance EqSequence S.ByteString where stripPrefix x y@@ -564,6 +919,15 @@ group = S.group elem = S.elem notElem = S.notElem+ {-# INLINE stripPrefix #-}+ {-# INLINE isPrefixOf #-}+ {-# INLINE stripSuffix #-}+ {-# INLINE isSuffixOf #-}+ {-# INLINE isInfixOf #-}+ {-# INLINE group #-}+ {-# INLINE groupAll #-}+ {-# INLINE elem #-}+ {-# INLINE notElem #-} instance EqSequence L.ByteString where stripPrefix x y@@ -578,6 +942,15 @@ group = L.group elem = L.elem notElem = L.notElem+ {-# INLINE stripPrefix #-}+ {-# INLINE isPrefixOf #-}+ {-# INLINE stripSuffix #-}+ {-# INLINE isSuffixOf #-}+ {-# INLINE isInfixOf #-}+ {-# INLINE group #-}+ {-# INLINE groupAll #-}+ {-# INLINE elem #-}+ {-# INLINE notElem #-} instance EqSequence T.Text where stripPrefix = T.stripPrefix@@ -586,6 +959,15 @@ isSuffixOf = T.isSuffixOf isInfixOf = T.isInfixOf group = T.group+ {-# INLINE stripPrefix #-}+ {-# INLINE isPrefixOf #-}+ {-# INLINE stripSuffix #-}+ {-# INLINE isSuffixOf #-}+ {-# INLINE isInfixOf #-}+ {-# INLINE group #-}+ {-# INLINE groupAll #-}+ {-# INLINE elem #-}+ {-# INLINE notElem #-} instance EqSequence TL.Text where stripPrefix = TL.stripPrefix@@ -594,6 +976,15 @@ isSuffixOf = TL.isSuffixOf isInfixOf = TL.isInfixOf group = TL.group+ {-# INLINE stripPrefix #-}+ {-# INLINE isPrefixOf #-}+ {-# INLINE stripSuffix #-}+ {-# INLINE isSuffixOf #-}+ {-# INLINE isInfixOf #-}+ {-# INLINE group #-}+ {-# INLINE groupAll #-}+ {-# INLINE elem #-}+ {-# INLINE notElem #-} instance Eq a => EqSequence (Seq.Seq a) instance Eq a => EqSequence (V.Vector a)@@ -603,12 +994,15 @@ class (EqSequence seq, MonoFoldableOrd seq) => OrdSequence seq where sort :: seq -> seq sort = fromList . List.sort . otoList+ {-# INLINE sort #-} instance Ord a => OrdSequence [a] where sort = List.sort+ {-# INLINE sort #-} instance OrdSequence S.ByteString where sort = S.sort+ {-# INLINE sort #-} instance OrdSequence L.ByteString instance OrdSequence T.Text@@ -635,6 +1029,7 @@ breakWord :: t -> (t, t) breakWord = fmap (dropWhile isSpace) . break isSpace+ {-# INLINE breakWord #-} breakLine :: t -> (t, t) breakLine =@@ -653,6 +1048,13 @@ toLower = TL.unpack . TL.toLower . TL.pack toUpper = TL.unpack . TL.toUpper . TL.pack toCaseFold = TL.unpack . TL.toCaseFold . TL.pack+ {-# INLINE words #-}+ {-# INLINE unwords #-}+ {-# INLINE lines #-}+ {-# INLINE unlines #-}+ {-# INLINE toLower #-}+ {-# INLINE toUpper #-}+ {-# INLINE toCaseFold #-} instance Textual T.Text where words = T.words@@ -662,6 +1064,13 @@ toLower = T.toLower toUpper = T.toUpper toCaseFold = T.toCaseFold+ {-# INLINE words #-}+ {-# INLINE unwords #-}+ {-# INLINE lines #-}+ {-# INLINE unlines #-}+ {-# INLINE toLower #-}+ {-# INLINE toUpper #-}+ {-# INLINE toCaseFold #-} instance Textual TL.Text where words = TL.words@@ -671,3 +1080,10 @@ toLower = TL.toLower toUpper = TL.toUpper toCaseFold = TL.toCaseFold+ {-# INLINE words #-}+ {-# INLINE unwords #-}+ {-# INLINE lines #-}+ {-# INLINE unlines #-}+ {-# INLINE toLower #-}+ {-# INLINE toUpper #-}+ {-# INLINE toCaseFold #-}
test/Spec.hs view
@@ -58,6 +58,19 @@ describe "groupAll" $ do it "list" $ groupAll ("abcabcabc" :: String) == ["aaa", "bbb", "ccc"] it "Text" $ groupAll ("abcabcabc" :: Text) == ["aaa", "bbb", "ccc"]+ describe "unsnoc" $ do+ let test name dummy = prop name $ \xs ->+ let seq' = fromList xs `asTypeOf` dummy+ in case (unsnoc seq', onull seq', onull xs) of+ (Nothing, True, True) -> return ()+ (Just (y, z), False, False) -> do+ (y SG.<> singleton z) `shouldBe` seq'+ snoc y z `shouldBe` seq'+ otoList (snoc y z) `shouldBe` xs+ x -> Prelude.error $ show x+ test "list" ([] :: [Int])+ test "Text" ("" :: Text)+ test "lazy ByteString" L.empty describe "groupAllOn" $ do it "list" $ groupAllOn (`mod` 3) ([1..9] :: [Int]) == [[1, 4, 7], [2, 5, 8], [3, 6, 9]] describe "breakWord" $ do