Data.List.permutations

(J. Waldmann, December 2021)

I was wondering what the code for Data.List.permutations https://hackage.haskell.org/package/base-4.16.0.0/docs/src/Data.OldList.html#permutations does, and how it came to be.

-- | The 'permutations' function returns the list of all permutations of the argument.
            --
            -- >>> permutations "abc"
            -- ["abc","bac","cba","bca","cab","acb"]
            permutations            :: [a] -> [[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)

Some references:

The original code (1996) was

-- permutations xs returns the list of all permutations of xs.
            -- e.g., permutations "abc" == ["abc","bac","bca","acb","cab","cba"]
            permutations            :: [a] -> [[a]]
            permutations []         =  [[]]
            permutations (x:xs)     =  [zs | ys <- permutations xs, zs <- interleave x ys ]
              where interleave          :: a -> [a] -> [[a]]
                    interleave x []     =  [[x]]
                    interleave x (y:ys) =  [x:y:ys] ++ map (y:) (interleave x ys)

The example shows that semantics did change.