### Abelian Actions on a Zipper

The goal here is to write an `Action`

class which depends on an `Abelian`

data type

and acts on a `Zipper`

type. Composition of left Abelian actions `Ab x G -> G`

and

evaluation are then given in the instance declaration for `Action (Zipper v)`

.

I begin by importing some useful modules and then defining a `Zipper`

.

```
import System.Random
import Text.Printf
import Data.Char
data Zipper a = Z {left :: [a], focus :: a, right :: [a]} deriving (Eq, Ord)
shiftLeft :: Zipper a -> Zipper a
shiftLeft (Z (a:as) b cs) = Z as a (b:cs)
shiftRight :: Zipper a -> Zipper a
shiftRight (Z as b (c:cs)) = Z (b:as) c cs
instance Show a => Show (Zipper a) where
show (Z a b c) = printf format (ff reverse a) (show b) (ff id c)
where
format = "[..%s { %s } %s..]\n"
ff f = unwords.(map show).f.(take 10)
```

Notice that we can shiftLeft and shiftRight along our `Zipper`

and further

there is a homespun `Show`

instance so that these potentially infinite Zippers

can be displayed easily.

```
integers :: Zipper Integer
integers = Z (map negate [1..]) 0 [1..]
alphabet :: Zipper Char
alphabet = Z sahpla 'a' (tail alphas)
where
alphas = [chr $ mod n 26 + 97 | n<- [0..]]
sahpla = [chr $ 122 - mod n 26 | n<- [0..]]
```

`alphabet`

Ok, so now there are Zippers. Now for an `Abelian`

data type which can be extended

naturally to the `Monoid`

class.

```
data Abelian = P Int | N Int
instance Eq Abelian where
(==) (P n) (N m) = (n==m) && (n==0)
(==) (P n) (P m) = n == m
(==) (N n) (N m) = n == m
instance Monoid Abelian where
mappend (P n) (P m) = P $ n + m
mappend (P n) (N m) | n - m >= 0 = P $ n - m
| otherwise = N $ n - m
mappend (N n) (P m) | m - n >= 0 = P $ m - n
| otherwise = N $ m - n
mappend (N n) (N m) = P $ n + m
mempty = P 0
```

Underlying `Abelian`

is the type `Int`

, which can be immediately recognized

as the de facto Abelian Object. `Abelian`

is first extended to the `Eq`

class

so that we can tell when two elements are the same. Next, instances for what is

meant by mempty and mappend are given for `Abelian`

objects. mappend is really

just addition and mempty just `0`

.

Next, the `Action`

class is defined so that given some `Action v`

one can

compose `Abelian`

operations and evaluate with respect to `v`

. In other words,

the `Action`

class characterizes left actions on `v`

.

Lastly, I give an instance of `Action Zipper`

.

```
class Action v where -- actions: Ab x G -> G
compose :: [Abelian] -> v a -> v a
eval :: Abelian -> v a -> v a
instance Action Zipper where
compose abs = eval (foldr mappend mempty abs)
eval (P n) = (!! n).iterate shiftRight
eval (N n) = (!! n).iterate shiftLeft
```

Now to test it out! Let’s apply `shortRandomWalk :: [Abelian]`

, a list of random Abelian operations, to alphabet and return the zipper’s focus.

```
shortRandomWalk :: [Abelian]
shortRandomWalk = take (2^15) $ run.(randomRs (-10, 10)).mkStdGen $ 32
where
run (x:xs) | x >= 0 = P x : run xs
| otherwise = N (abs x) : run xs
focus.compose shortRandomWalk $ alphabet
```

nice.