Implement stimes for sequences
authorDavid Feuer <David.Feuer@gmail.com>
Thu, 11 Apr 2019 04:29:31 +0000 (00:29 -0400)
committerDavid Feuer <David.Feuer@gmail.com>
Thu, 11 Apr 2019 04:49:44 +0000 (00:49 -0400)
Implement `stimes` for sequences using `cycleNTimes`. This makes
it work when the argument is 0 (unlike the default). `cycleNTimes`
is faster and lazier than `stimesMonoid` because it takes advantage
of the finger tree structure of sequences.

Closes #618

Data/Sequence/Internal.hs
changelog.md
tests/seq-properties.hs

index 9524044..a543a85 100644 (file)
@@ -891,6 +891,7 @@ instance Monoid (Seq a) where
 -- | @since 0.5.7
 instance Semigroup.Semigroup (Seq a) where
     (<>)    = (><)
+    stimes = cycleNTimes . fromIntegral
 #endif
 
 INSTANCE_TYPEABLE1(Seq)
index fccb85a..e3f5bda 100644 (file)
@@ -1,11 +1,14 @@
 # Changelog for [`containers` package](http://github.com/haskell/containers)
 
-## 0.6.0.2
+## 0.6.0.2?
 
 * Fix Foldable instance for IntMap, which previously placed positively
   keyed entries before negatively keyed ones for `fold`, `foldMap`, and
   `traverse`.
 
+* Make `stimes` for sequences work with 0 arguments, and make it more
+  efficient.
+
 ## 0.6.0.1
 
 * Released with GHC 8.6
index 7f29ade..8f0a2b8 100644 (file)
@@ -25,6 +25,9 @@ import Data.Functor ((<$>), (<$))
 import Data.Maybe
 import Data.Function (on)
 import Data.Monoid (Monoid(..), All(..), Endo(..), Dual(..))
+#if MIN_VERSION_base(4,9,0)
+import Data.Semigroup (stimes, stimesMonoid)
+#endif
 import Data.Traversable (Traversable(traverse), sequenceA)
 import Prelude hiding (
   lookup, null, length, take, drop, splitAt,
@@ -152,6 +155,9 @@ main = defaultMain
        , testProperty "Right view pattern" prop_viewr_pat
        , testProperty "Right view constructor" prop_viewr_con
 #endif
+#if MIN_VERSION_base(4,9,0)
+       , testProperty "stimes" prop_stimes
+#endif
        ]
 
 ------------------------------------------------------------------------
@@ -878,6 +884,14 @@ prop_bind :: Seq A -> Fun A (Seq B) -> Bool
 prop_bind xs (Fun _ f) =
     toList' (xs >>= f) ~= (toList xs >>= toList . f)
 
+-- Semigroup operations
+
+#if MIN_VERSION_base(4,9,0)
+prop_stimes :: NonNegative Int -> Seq A -> Property
+prop_stimes (NonNegative n) s =
+  stimes n s === stimesMonoid n s
+#endif
+
 -- MonadFix operation
 
 -- It's exceedingly difficult to construct a proper QuickCheck