Skip to content

Commit b21bf11

Browse files
committed
Add changelog + @since for next/prevPermutation
This adds a changelog entry and `@since` annotations for: - Optimization of `Data.Vector.Generic.Mutable.nextPermutation` - Addition of `Data.Vector.Generic.Mutable.prevPermutation(By)` - Addition of `Data.Vector.Generic.Mutable.nextPermutationBy` This also tweaks the haddock comments of the functions for `Data.Vector.*.Mutable.(next|prev)Permutation(By)?` for a better readability.
1 parent 54c59a6 commit b21bf11

File tree

7 files changed

+120
-74
lines changed

7 files changed

+120
-74
lines changed

vector/changelog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# Changes in version 0.13.2.0
2+
3+
* We had some improvements on `*.Mutable.{next,prev}Permutation{,By}`
4+
[#498](https://github.com/haskell/vector/pull/498):
5+
* Add `*.Mutable.prevPermutation{,By}` and `*.Mutable.nextPermutationBy`
6+
* Improve time performance. We may now expect good specialization supported by inlining.
7+
The implementation has also been algorithmically updated: in the previous implementation
8+
the full enumeration of all the permutations of `[1..n]` took Omega(n*n!), but it now takes O(n!).
9+
* Add tests for `{next,prev}Permutation`
10+
111
# Changes in version 0.13.1.0
212

313
* Specialized variants of `findIndexR` are reexported for all vector

vector/src/Data/Vector/Generic/Mutable.hs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,35 +1217,41 @@ partitionWithUnknown f s
12171217

12181218

12191219
-- | Compute the (lexicographically) next permutation of the given vector in-place.
1220-
-- Returns False when the input is the last permutation; in this case the vector
1221-
-- will not get updated, as opposed to the behavior of the C++ function
1222-
-- @std::next_permutation@.
1220+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
1221+
-- weakly descending order. In this case the vector will not get updated,
1222+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
12231223
nextPermutation :: (PrimMonad m, Ord e, MVector v e) => v (PrimState m) e -> m Bool
12241224
{-# INLINE nextPermutation #-}
12251225
nextPermutation = nextPermutationByLt (<)
12261226

12271227
-- | Compute the (lexicographically) next permutation of the given vector in-place,
12281228
-- using the provided comparison function.
1229-
-- Returns False when the input is the last permutation; in this case the vector
1230-
-- will not get updated, as opposed to the behavior of the C++ function
1231-
-- @std::next_permutation@.
1229+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
1230+
-- weakly descending order. In this case the vector will not get updated,
1231+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
1232+
--
1233+
-- @since 0.13.2.0
12321234
nextPermutationBy :: (PrimMonad m, MVector v e) => (e -> e -> Ordering) -> v (PrimState m) e -> m Bool
12331235
{-# INLINE nextPermutationBy #-}
12341236
nextPermutationBy cmp = nextPermutationByLt (\x y -> cmp x y == LT)
12351237

12361238
-- | Compute the (lexicographically) previous permutation of the given vector in-place.
1237-
-- Returns False when the input is the last permutation; in this case the vector
1238-
-- will not get updated, as opposed to the behavior of the C++ function
1239-
-- @std::next_permutation@.
1239+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
1240+
-- weakly ascending order. In this case the vector will not get updated,
1241+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
1242+
--
1243+
-- @since 0.13.2.0
12401244
prevPermutation :: (PrimMonad m, Ord e, MVector v e) => v (PrimState m) e -> m Bool
12411245
{-# INLINE prevPermutation #-}
12421246
prevPermutation = nextPermutationByLt (>)
12431247

12441248
-- | Compute the (lexicographically) previous permutation of the given vector in-place,
12451249
-- using the provided comparison function.
1246-
-- Returns False when the input is the last permutation; in this case the vector
1247-
-- will not get updated, as opposed to the behavior of the C++ function
1248-
-- @std::next_permutation@.
1250+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
1251+
-- weakly ascending order. In this case the vector will not get updated,
1252+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
1253+
--
1254+
-- @since 0.13.2.0
12491255
prevPermutationBy :: (PrimMonad m, MVector v e) => (e -> e -> Ordering) -> v (PrimState m) e -> m Bool
12501256
{-# INLINE prevPermutationBy #-}
12511257
prevPermutationBy cmp = nextPermutationByLt (\x y -> cmp x y == GT)

vector/src/Data/Vector/Mutable.hs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -575,35 +575,41 @@ unsafeMove = G.unsafeMove
575575
-- -----------------
576576

577577
-- | Compute the (lexicographically) next permutation of the given vector in-place.
578-
-- Returns False when the input is the last permutation; in this case the vector
579-
-- will not get updated, as opposed to the behavior of the C++ function
580-
-- @std::next_permutation@.
578+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
579+
-- weakly descending order. In this case the vector will not get updated,
580+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
581581
nextPermutation :: (PrimMonad m, Ord e) => MVector (PrimState m) e -> m Bool
582582
{-# INLINE nextPermutation #-}
583583
nextPermutation = G.nextPermutation
584584

585585
-- | Compute the (lexicographically) next permutation of the given vector in-place,
586586
-- using the provided comparison function.
587-
-- Returns False when the input is the last permutation; in this case the vector
588-
-- will not get updated, as opposed to the behavior of the C++ function
589-
-- @std::next_permutation@.
587+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
588+
-- weakly descending order. In this case the vector will not get updated,
589+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
590+
--
591+
-- @since 0.13.2.0
590592
nextPermutationBy :: PrimMonad m => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
591593
{-# INLINE nextPermutationBy #-}
592594
nextPermutationBy = G.nextPermutationBy
593595

594596
-- | Compute the (lexicographically) previous permutation of the given vector in-place.
595-
-- Returns False when the input is the last permutation; in this case the vector
596-
-- will not get updated, as opposed to the behavior of the C++ function
597-
-- @std::next_permutation@.
597+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
598+
-- weakly ascending order. In this case the vector will not get updated,
599+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
600+
--
601+
-- @since 0.13.2.0
598602
prevPermutation :: (PrimMonad m, Ord e) => MVector (PrimState m) e -> m Bool
599603
{-# INLINE prevPermutation #-}
600604
prevPermutation = G.prevPermutation
601605

602606
-- | Compute the (lexicographically) previous permutation of the given vector in-place,
603607
-- using the provided comparison function.
604-
-- Returns False when the input is the last permutation; in this case the vector
605-
-- will not get updated, as opposed to the behavior of the C++ function
606-
-- @std::next_permutation@.
608+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
609+
-- weakly ascending order. In this case the vector will not get updated,
610+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
611+
--
612+
-- @since 0.13.2.0
607613
prevPermutationBy :: PrimMonad m => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
608614
{-# INLINE prevPermutationBy #-}
609615
prevPermutationBy = G.prevPermutationBy

vector/src/Data/Vector/Primitive/Mutable.hs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -541,35 +541,41 @@ unsafeMove = G.unsafeMove
541541
-- -----------------
542542

543543
-- | Compute the (lexicographically) next permutation of the given vector in-place.
544-
-- Returns False when the input is the last permutation; in this case the vector
545-
-- will not get updated, as opposed to the behavior of the C++ function
546-
-- @std::next_permutation@.
544+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
545+
-- weakly descending order. In this case the vector will not get updated,
546+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
547547
nextPermutation :: (PrimMonad m,Ord e,Prim e) => MVector (PrimState m) e -> m Bool
548548
{-# INLINE nextPermutation #-}
549549
nextPermutation = G.nextPermutation
550550

551551
-- | Compute the (lexicographically) next permutation of the given vector in-place,
552552
-- using the provided comparison function.
553-
-- Returns False when the input is the last permutation; in this case the vector
554-
-- will not get updated, as opposed to the behavior of the C++ function
555-
-- @std::next_permutation@.
553+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
554+
-- weakly descending order. In this case the vector will not get updated,
555+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
556+
--
557+
-- @since 0.13.2.0
556558
nextPermutationBy :: (PrimMonad m,Prim e) => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
557559
{-# INLINE nextPermutationBy #-}
558560
nextPermutationBy = G.nextPermutationBy
559561

560562
-- | Compute the (lexicographically) previous permutation of the given vector in-place.
561-
-- Returns False when the input is the last permutation; in this case the vector
562-
-- will not get updated, as opposed to the behavior of the C++ function
563-
-- @std::next_permutation@.
563+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
564+
-- weakly ascending order. In this case the vector will not get updated,
565+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
566+
--
567+
-- @since 0.13.2.0
564568
prevPermutation :: (PrimMonad m,Ord e,Prim e) => MVector (PrimState m) e -> m Bool
565569
{-# INLINE prevPermutation #-}
566570
prevPermutation = G.prevPermutation
567571

568572
-- | Compute the (lexicographically) previous permutation of the given vector in-place,
569573
-- using the provided comparison function.
570-
-- Returns False when the input is the last permutation; in this case the vector
571-
-- will not get updated, as opposed to the behavior of the C++ function
572-
-- @std::next_permutation@.
574+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
575+
-- weakly ascending order. In this case the vector will not get updated,
576+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
577+
--
578+
-- @since 0.13.2.0
573579
prevPermutationBy :: (PrimMonad m,Prim e) => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
574580
{-# INLINE prevPermutationBy #-}
575581
prevPermutationBy = G.prevPermutationBy

vector/src/Data/Vector/Storable/Mutable.hs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -642,35 +642,41 @@ unsafeMove = G.unsafeMove
642642
-- -----------------
643643

644644
-- | Compute the (lexicographically) next permutation of the given vector in-place.
645-
-- Returns False when the input is the last permutation; in this case the vector
646-
-- will not get updated, as opposed to the behavior of the C++ function
647-
-- @std::next_permutation@.
645+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
646+
-- weakly descending order. In this case the vector will not get updated,
647+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
648648
nextPermutation :: (PrimMonad m, Storable e, Ord e) => MVector (PrimState m) e -> m Bool
649649
{-# INLINE nextPermutation #-}
650650
nextPermutation = G.nextPermutation
651651

652652
-- | Compute the (lexicographically) next permutation of the given vector in-place,
653653
-- using the provided comparison function.
654-
-- Returns False when the input is the last permutation; in this case the vector
655-
-- will not get updated, as opposed to the behavior of the C++ function
656-
-- @std::next_permutation@.
654+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
655+
-- weakly descending order. In this case the vector will not get updated,
656+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
657+
--
658+
-- @since 0.13.2.0
657659
nextPermutationBy :: (PrimMonad m, Storable e) => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
658660
{-# INLINE nextPermutationBy #-}
659661
nextPermutationBy = G.nextPermutationBy
660662

661663
-- | Compute the (lexicographically) previous permutation of the given vector in-place.
662-
-- Returns False when the input is the last permutation; in this case the vector
663-
-- will not get updated, as opposed to the behavior of the C++ function
664-
-- @std::next_permutation@.
664+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
665+
-- weakly ascending order. In this case the vector will not get updated,
666+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
667+
--
668+
-- @since 0.13.2.0
665669
prevPermutation :: (PrimMonad m, Storable e, Ord e) => MVector (PrimState m) e -> m Bool
666670
{-# INLINE prevPermutation #-}
667671
prevPermutation = G.prevPermutation
668672

669673
-- | Compute the (lexicographically) previous permutation of the given vector in-place,
670674
-- using the provided comparison function.
671-
-- Returns False when the input is the last permutation; in this case the vector
672-
-- will not get updated, as opposed to the behavior of the C++ function
673-
-- @std::next_permutation@.
675+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
676+
-- weakly ascending order. In this case the vector will not get updated,
677+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
678+
--
679+
-- @since 0.13.2.0
674680
prevPermutationBy :: (PrimMonad m, Storable e) => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
675681
{-# INLINE prevPermutationBy #-}
676682
prevPermutationBy = G.prevPermutationBy

vector/src/Data/Vector/Strict/Mutable.hs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -555,9 +555,9 @@ unsafeMove = G.unsafeMove
555555
-- -----------------
556556

557557
-- | Compute the (lexicographically) next permutation of the given vector in-place.
558-
-- Returns False when the input is the last permutation; in this case the vector
559-
-- will not get updated, as opposed to the behavior of the C++ function
560-
-- @std::next_permutation@.
558+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
559+
-- weakly descending order. In this case the vector will not get updated,
560+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
561561
--
562562
-- @since 0.13.2.0
563563
nextPermutation :: (PrimMonad m, Ord e) => MVector (PrimState m) e -> m Bool
@@ -566,27 +566,33 @@ nextPermutation = G.nextPermutation
566566

567567
-- | Compute the (lexicographically) next permutation of the given vector in-place,
568568
-- using the provided comparison function.
569-
-- Returns False when the input is the last permutation; in this case the vector
570-
-- will not get updated, as opposed to the behavior of the C++ function
571-
-- @std::next_permutation@.
572-
nextPermutationBy :: (PrimMonad m) => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
569+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
570+
-- weakly descending order. In this case the vector will not get updated,
571+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
572+
--
573+
-- @since 0.13.2.0
574+
nextPermutationBy :: PrimMonad m => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
573575
{-# INLINE nextPermutationBy #-}
574576
nextPermutationBy = G.nextPermutationBy
575577

576578
-- | Compute the (lexicographically) previous permutation of the given vector in-place.
577-
-- Returns False when the input is the last permutation; in this case the vector
578-
-- will not get updated, as opposed to the behavior of the C++ function
579-
-- @std::next_permutation@.
579+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
580+
-- weakly ascending order. In this case the vector will not get updated,
581+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
582+
--
583+
-- @since 0.13.2.0
580584
prevPermutation :: (PrimMonad m, Ord e) => MVector (PrimState m) e -> m Bool
581585
{-# INLINE prevPermutation #-}
582586
prevPermutation = G.prevPermutation
583587

584588
-- | Compute the (lexicographically) previous permutation of the given vector in-place,
585589
-- using the provided comparison function.
586-
-- Returns False when the input is the last permutation; in this case the vector
587-
-- will not get updated, as opposed to the behavior of the C++ function
588-
-- @std::next_permutation@.
589-
prevPermutationBy :: (PrimMonad m) => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
590+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
591+
-- weakly ascending order. In this case the vector will not get updated,
592+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
593+
--
594+
-- @since 0.13.2.0
595+
prevPermutationBy :: PrimMonad m => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
590596
{-# INLINE prevPermutationBy #-}
591597
prevPermutationBy = G.prevPermutationBy
592598

vector/src/Data/Vector/Unboxed/Mutable.hs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -444,35 +444,41 @@ unsafeMove = G.unsafeMove
444444
-- -----------------
445445

446446
-- | Compute the (lexicographically) next permutation of the given vector in-place.
447-
-- Returns False when the input is the last permutation; in this case the vector
448-
-- will not get updated, as opposed to the behavior of the C++ function
449-
-- @std::next_permutation@.
447+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
448+
-- weakly descending order. In this case the vector will not get updated,
449+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
450450
nextPermutation :: (PrimMonad m,Ord e,Unbox e) => MVector (PrimState m) e -> m Bool
451451
{-# INLINE nextPermutation #-}
452452
nextPermutation = G.nextPermutation
453453

454454
-- | Compute the (lexicographically) next permutation of the given vector in-place,
455455
-- using the provided comparison function.
456-
-- Returns False when the input is the last permutation; in this case the vector
457-
-- will not get updated, as opposed to the behavior of the C++ function
458-
-- @std::next_permutation@.
456+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
457+
-- weakly descending order. In this case the vector will not get updated,
458+
-- as opposed to the behavior of the C++ function @std::next_permutation@.
459+
--
460+
-- @since 0.13.2.0
459461
nextPermutationBy :: (PrimMonad m,Unbox e) => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
460462
{-# INLINE nextPermutationBy #-}
461463
nextPermutationBy = G.nextPermutationBy
462464

463465
-- | Compute the (lexicographically) previous permutation of the given vector in-place.
464-
-- Returns False when the input is the last permutation; in this case the vector
465-
-- will not get updated, as opposed to the behavior of the C++ function
466-
-- @std::next_permutation@.
466+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
467+
-- weakly ascending order. In this case the vector will not get updated,
468+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
469+
--
470+
-- @since 0.13.2.0
467471
prevPermutation :: (PrimMonad m,Ord e,Unbox e) => MVector (PrimState m) e -> m Bool
468472
{-# INLINE prevPermutation #-}
469473
prevPermutation = G.prevPermutation
470474

471475
-- | Compute the (lexicographically) previous permutation of the given vector in-place,
472476
-- using the provided comparison function.
473-
-- Returns False when the input is the last permutation; in this case the vector
474-
-- will not get updated, as opposed to the behavior of the C++ function
475-
-- @std::next_permutation@.
477+
-- Returns False when the input is the last item in the enumeration, i.e., if it is in
478+
-- weakly ascending order. In this case the vector will not get updated,
479+
-- as opposed to the behavior of the C++ function @std::prev_permutation@.
480+
--
481+
-- @since 0.13.2.0
476482
prevPermutationBy :: (PrimMonad m,Unbox e) => (e -> e -> Ordering) -> MVector (PrimState m) e -> m Bool
477483
{-# INLINE prevPermutationBy #-}
478484
prevPermutationBy = G.prevPermutationBy

0 commit comments

Comments
 (0)