{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances #-} module CircularShifter where import Data.List import Data.Array.IO class Line c where rotate :: c a -> c a rotateAll :: c a -> c (c a) instance Line [] where -- rotate :: [a] -> [a] rotate [] = [] rotate (x:xs) = xs ++ [x] -- rotateAll :: [a] -> [[a]] rotateAll xs = take (length xs) (iterate rotate xs) class (Monad m) => CircularShifter a b c m where circularShift :: b (c a) -> m (b (c (c a))) instance (Monad m) => CircularShifter a [] [] m where circularShift = return . map rotateAll instance (Ix i, Monad m, Line c, MArray a (c x) m, MArray a (c (c x)) m) => CircularShifter x (a i) c m where circularShift v = mapArray rotateAll v