module RingList exposing (..) type alias RingList a = { before : List a , focus : a , after : List a } {- Basic conversion -} fromList : a -> List a -> RingList a fromList a l = RingList [] a l toList : RingList a -> List a toList rl = List.reverse rl.before ++ [rl.focus] ++ rl.after {- Functor like things -} map : (a -> b) -> RingList a -> RingList b map f rl = RingList (List.map f rl.before) (f rl.focus) (List.map f rl.after) edit : (a -> a) -> RingList a -> RingList a edit f rl = RingList rl.before (rl.focus |> f) rl.after {- Comonad functions -} extract : RingList a -> a extract rl = rl.focus duplicate : RingList a -> RingList (RingList a) duplicate rl = let lefts = iterate1N (List.length rl.before) shiftRight rl rights = iterate1N (List.length rl.after) shiftLeft rl in RingList lefts rl rights extend : (RingList a -> b) -> RingList a -> RingList b extend f w = map f (duplicate w) (=>>) : RingList a -> (RingList a -> b) -> RingList b (=>>) = flip extend {- Domain functions -} shiftLeft : RingList a -> RingList a shiftLeft rl = case rl.after of [] -> case List.reverse rl.before of [] -> RingList [] rl.focus [] x::xs -> RingList [rl.focus] x xs x::xs -> RingList (rl.focus :: rl.before) x xs shiftRight : RingList a -> RingList a shiftRight rl = case rl.before of [] -> case List.reverse rl.after of [] -> RingList [] rl.focus [] x::xs -> RingList xs x [rl.focus] x::xs -> RingList xs x (rl.focus :: rl.after) {- From here we have private functions -} iterate1N : Int -> (a -> a) -> a -> List a iterate1N n f a = case n of 0 -> [] m -> f a :: List.map f (iterate1N (m - 1) f a)