Начнем со списка, [1..4]
. Давайте повторим это для вечности:
>>> cycle [1..4]
[1,2,3,4,1,2,3,4,1,2,3,4,...
Теперь давайте возьмем его, скажем, второй индекс:
>>> take 4 $ drop (2-1) $ cycle [1..4]
[2,3,4,1]
Мы можем обобщить это, назвав функцию:
slice n = take 4 $ drop n $ cycle [1..4]
Чтобы получить все возможные циклические перестановки, нам нужно только выбрать n от 1 до 4:
>>> map slice [1..4]
[[2,3,4,1],[3,4,1,2],[4,1,2,3],[1,2,3,4]]
Теперь, как мы можем заставить эту работу работать с произвольной строкой? Давайте переопределим фрагмент, чтобы принять строку:
slice s n = take (length s) $ drop n $ cycle s
И поэтому наша функция циклических перестановок может быть определена следующим образом:
cyclicPerms s = map (slice s) [1..(length s)]
Тестирование:
>>> cyclicPerms "abcde"
["bcdea","cdeab","deabc","eabcd","abcde"]