(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.