In today’s Programming Praxis exercise, our goal is to write a function to rotate an array a selected number of places. Let’s get started, shall we?
While the assignment mentions arrays specifically, we’re going to be using plain lists, for the following reasons:
1. In Haskell lists are a far more common data structure than arrays.
2. The algorithm used in the Scheme solution is O(n) anyway, so it doesn’t matter all that much in terms of performance.
3. This way we can show off an alternative method, which is more fun than just implementing the provided algorithm in another language.
Instead of the triple reversing approach, we use a more straightforward method: what we effectively do when rotating a list is splitting it into a left and a right part and exchanging their places. So let’s just do that, making sure to keep the splitting point within the bounds of the list:
rotate :: Int -> [a] -> [a] rotate _  =  rotate n xs = b ++ a where (a,b) = splitAt (mod n $ length xs) xs
To see if it works, we test all the possible corner cases mentioned in the assignment, including the empty list, which the provided solution fails on (which is another reminder of why you should always consider all possible edge cases). To be honest, so did mine until I wrote ‘all possible edge cases’ and figured I’d better check if that was actually the case 🙂
main :: IO () main = do print $ rotate 1  == ( :: [Int]) print $ rotate 3 [1..3] == [1..3] print $ rotate 3 [1..3] == [1..3] print $ rotate 2 [1..6] == [3,4,5,6,1,2] print $ rotate 8 [1..6] == rotate 2 [1..6] print $ rotate (-2) (rotate 2 [1..6]) == [1..6]