packages feed

mono-traversable 1.0.0.1 → 1.0.1

raw patch · 5 files changed

+72/−3 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.MonoTraversable: replaceElem :: (MonoFunctor mono, Eq (Element mono)) => Element mono -> Element mono -> mono -> mono
+ Data.MonoTraversable: replaceElemLazyText :: Char -> Char -> Text -> Text
+ Data.MonoTraversable: replaceElemStrictText :: Char -> Char -> Text -> Text
+ Data.Sequences: replaceSeq :: (IsSequence seq, Eq (Element seq)) => seq -> seq -> seq -> seq
+ Data.Sequences: replaceSeqLazyText :: Text -> Text -> Text -> Text
+ Data.Sequences: replaceSeqStrictText :: Text -> Text -> Text -> Text

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+## 1.0.1++* Add `replaceElem` and `replaceSeq` [#107](https://github.com/snoyberg/mono-traversable/pull/107)+ ## 1.0.0.1  * Add missing export [#101](https://github.com/snoyberg/mono-traversable/pull/101)
mono-traversable.cabal view
@@ -1,5 +1,5 @@ name:                mono-traversable-version:             1.0.0.1+version:             1.0.1 synopsis:            Type classes for mapping, folding, and traversing monomorphic containers description:         Monomorphic variants of the Functor, Foldable, and Traversable typeclasses. If you understand Haskell's basic typeclasses, you understand mono-traversable. In addition to what you are used to, it adds on an IsSequence typeclass and has code for marking data structures as non-empty. homepage:            https://github.com/snoyberg/mono-traversable
src/Data/MonoTraversable.hs view
@@ -45,7 +45,7 @@ import           GHC.Exts             (build) import           Prelude              (Bool (..), const, Char, flip, IO, Maybe (..), Either (..),                                        (+), Integral, Ordering (..), compare, fromIntegral, Num, (>=),-                                       seq, otherwise, Eq, Ord, (-), (*))+                                       (==), seq, otherwise, Eq, Ord, (-), (*)) import qualified Prelude import qualified Data.ByteString.Internal as Unsafe import qualified Foreign.ForeignPtr.Unsafe as Unsafe@@ -198,6 +198,21 @@ instance VS.Storable a => MonoFunctor (VS.Vector a) where     omap = VS.map     {-# INLINE omap #-}++-- | @'replaceElem' old new@ replaces all @old@ elements with @new@.+--+-- @since 1.0.1+replaceElem :: (MonoFunctor mono, Eq (Element mono)) => Element mono -> Element mono -> mono -> mono+replaceElem old new = omap (\x -> if x == old then new else x)++{-# INLINE [0] replaceElem #-}+{-# RULES "strict Text replaceElem" replaceElem = replaceElemStrictText #-}+replaceElemStrictText :: Char -> Char -> T.Text -> T.Text+replaceElemStrictText old new = T.replace (T.singleton old) (T.singleton new)+{-# RULES "lazy Text replaceElem" replaceElem = replaceElemLazyText #-}+replaceElemLazyText :: Char -> Char -> TL.Text -> TL.Text+replaceElemLazyText old new = TL.replace (TL.singleton old) (TL.singleton new)+  -- | Monomorphic containers that can be folded. class MonoFoldable mono where
src/Data/Sequences.hs view
@@ -1169,7 +1169,7 @@ -- | @'splitSeq'@ splits a sequence into components delimited by -- separator subsequence. 'splitSeq' is the right inverse of 'intercalate': ----- > intercalate x . splitSeq x === id+-- > ointercalate x . splitSeq x === id -- -- 'splitElem' can be considered a special case of 'splitSeq' --@@ -1192,6 +1192,15 @@ splitSeq :: (IsSequence seq, Eq (Element seq)) => seq -> seq -> [seq] splitSeq sep = List.map fromList . List.splitOn (otoList sep) . otoList +-- | @'replaceSeq' old new@ replaces all @old@ subsequences with @new@.+--+-- > replaceSeq old new === ointercalate new . splitSeq old+--+-- @since 1.0.1++replaceSeq :: (IsSequence seq, Eq (Element seq)) => seq -> seq -> seq -> seq+replaceSeq old new = ointercalate new . splitSeq old+ -- | 'stripPrefix' drops the given prefix from a sequence. -- It returns 'Nothing' if the sequence did not start with the prefix -- given, or 'Just' the sequence after the prefix, if it does.@@ -1259,8 +1268,10 @@ -- @since 0.10.2 deleteBy :: (IsSequence seq, Eq (Element seq)) => (Element seq -> Element seq -> Bool) -> Element seq -> seq -> seq deleteBy eq x = fromList . List.deleteBy eq x . otoList+ {-# INLINE [0] splitElem #-} {-# INLINE [0] splitSeq #-}+{-# INLINE [0] replaceSeq #-} {-# INLINE [0] isPrefixOf #-} {-# INLINE [0] isSuffixOf #-} {-# INLINE [0] isInfixOf #-}@@ -1325,6 +1336,7 @@     | otherwise = Nothing  {-# RULES "strict Text splitSeq" splitSeq = splitSeqStrictText #-}+{-# RULES "strict Text replaceSeq" replaceSeq = replaceSeqStrictText #-} {-# RULES "strict Text stripPrefix" stripPrefix = T.stripPrefix #-} {-# RULES "strict Text stripSuffix" stripSuffix = T.stripSuffix #-} {-# RULES "strict Text group" group = T.group #-}@@ -1337,7 +1349,13 @@     | T.null sep = (:) T.empty . List.map singleton . T.unpack     | otherwise = T.splitOn sep +replaceSeqStrictText :: T.Text -> T.Text -> T.Text -> T.Text+replaceSeqStrictText old new+    | T.null old = T.intercalate new . splitSeqStrictText old+    | otherwise = T.replace old new+ {-# RULES "lazy Text splitSeq" splitSeq = splitSeqLazyText #-}+{-# RULES "lazy Text replaceSeq" replaceSeq = replaceSeqLazyText #-} {-# RULES "lazy Text stripPrefix" stripPrefix = TL.stripPrefix #-} {-# RULES "lazy Text stripSuffix" stripSuffix = TL.stripSuffix #-} {-# RULES "lazy Text group" group = TL.group #-}@@ -1349,6 +1367,11 @@ splitSeqLazyText sep     | TL.null sep = (:) TL.empty . List.map singleton . TL.unpack     | otherwise = TL.splitOn sep++replaceSeqLazyText :: TL.Text -> TL.Text -> TL.Text -> TL.Text+replaceSeqLazyText old new+    | TL.null old = TL.intercalate new . splitSeqLazyText old+    | otherwise = TL.replace old new  -- | Sort a ordered sequence. --
test/Spec.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE CPP #-}  module Spec where @@ -373,6 +374,32 @@             let x1 = Foldl.fold Foldl.length (xs :: [Int])                 x2 = Foldl.purely ofoldlUnwrap Foldl.length xs             x2 @?= x1++    describe "Replacing" $ do+        let test typ dummy = describe typ $ do+                prop "replaceElem old new === omap (\\x -> if x == old then new else x)" $+                    -- replace random element or any random value with random new value+                    \x list new -> forAll (elements (x:list)) $ \old ->+                    let seq' = fromListAs list dummy+                    in replaceElem old new seq' @?= omap (\x -> if x == old then new else x) seq'+#if MIN_VERSION_QuickCheck(2,8,0)+                prop "replaceSeq old new === ointercalate new . splitSeq old" $+                    -- replace random subsequence with random new sequence+                    \list new -> forAll (sublistOf list) $ \old ->+                    let [seq', old', new'] = map (`fromListAs` dummy) [list, old, new]+                    in replaceSeq old' new' seq' @?= ointercalate new' (splitSeq old' seq')+                prop "replaceSeq old old === id" $ \list -> forAll (sublistOf list) $ \old ->+                    let [seq', old'] = map (`fromListAs` dummy) [list, old]+                    in replaceSeq old' old' seq' @?= seq'+#endif+        test "List" ([] :: [Int])+        test "Vector" (V.empty :: V.Vector Int)+        test "Storable Vector" (VS.empty :: VS.Vector Int)+        test "Unboxed Vector" (U.empty :: U.Vector Int)+        test "Strict ByteString" S.empty+        test "Lazy ByteString" L.empty+        test "Strict Text" T.empty+        test "Lazy Text" TL.empty      describe "Sorting" $ do         let test typ dummy = describe typ $ do