Cellular automata in Elm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

58 lines
1.6 KiB

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)