diff --git a/src/Relude/List.hs b/src/Relude/List.hs index 5ab54d93..ab07e362 100644 --- a/src/Relude/List.hs +++ b/src/Relude/List.hs @@ -20,16 +20,18 @@ module Relude.List , (!!?) , maybeAt , partitionWith + , permutations ) where import Relude.Base ((<)) import Relude.Bool (otherwise) -import Relude.Function (flip, (.)) +import Relude.Function (flip, (.), id) import Relude.List.NonEmpty import Relude.List.Reexport import Relude.Monad (Either, Maybe (..), partitionEithers) import Relude.Numeric (Int, (-)) +import Relude.Foldable (foldr) -- $setup @@ -108,6 +110,29 @@ partitionWith :: (a -> Either b c) -> [a] -> ([b], [c]) partitionWith f = partitionEithers . map f {-# INLINE partitionWith #-} +{- | The 'permutations' function returns the list of all permutations of the argument. +Unlike its Prelude implementation, thiv version returns NonEmpty. + +>>> permutations "abc" +"abc" :| ["bac","cba","bca","cab","acb"] + +>>> permutations [] +[] :| [] + +@since 1.1.0.0 +-} +permutations :: [a] -> NonEmpty [a] +permutations xs0 = xs0 :| perms xs0 [] + where + perms [] _ = [] + perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is) + where interleave xs r = let (_,zs) = interleave' id xs r in zs + interleave' _ [] r = (ts, r) + interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r + in (y:us, f (t:y:us) : zs) +{-# INLINE permutations #-} + + {- $reexport Most of the "Data.List" types and function. diff --git a/src/Relude/List/Reexport.hs b/src/Relude/List/Reexport.hs index e3c8dbcd..f62324d0 100644 --- a/src/Relude/List/Reexport.hs +++ b/src/Relude/List/Reexport.hs @@ -21,7 +21,7 @@ module Relude.List.Reexport import Data.List (break, drop, dropWhile, filter, genericDrop, genericLength, genericReplicate, genericSplitAt, genericTake, group, inits, intercalate, intersperse, isPrefixOf, - iterate, map, permutations, repeat, replicate, reverse, scanl, scanl', scanl1, + iterate, map, repeat, replicate, reverse, scanl, scanl', scanl1, scanr, scanr1, sort, sortBy, sortOn, span, splitAt, subsequences, tails, take, takeWhile, transpose, uncons, unfoldr, unzip, unzip3, zip, zip3, zipWith, (++)) import GHC.Exts (sortWith)