Cellular Automata Using Comonads

I have recently come across an article about implementing a one-dimensional cellular automaton using comonads. But this material is a bit outdated. Therefore, I’ve decided to write an article of my own and consider two-dimensional cellular automata by the example of The Game of Life:

Universe

Let’s take a look at Universe data type that is defined the following way:

data Universe a = Universe [a] a [a]

It’s a doubly infinite list focusing on some element that we can shift using the following functions:

It’s basically a zipper, but we can consider it as a constant C-pointer to the infinite memory area as all increment and decrement operations are applicable to it. But how do we dereference it? Let’s define the function that will get a focused value:

Comonads

Therefore, Universe forms a comonad and next function corresponds to (=>>) operator. A comonad is a monad dual. Thus, we can see the following analogies between their operations. For instance, join superposes embedded scopes, while duplicate, on the contrary, doubles the scope; return locates into the scope and extract extracts from it, etc.

A Two-Dimensional Cellular Automaton

Now, we can just as well implement a two-dimensional cellular automaton. To begin with, let’s declare a type of the two-dimensional Universe:

That’s almost it! We just should define the rule and apply it with the help of (=>>). In The Game of Life, a new state of a cell depends on the state of neighboring cells. Thus, let’s define the function of their location:

Summary

Thus, we can implement any cellular automaton by simply defining rule function. Thanks to lazy calculations, we get the infinite field as a present, though it leads to linear memory consumption.

Since we apply the rule to each element of the infinite list, to calculate the cells that have not been referred to, we will have to go through all the previous steps. Therefore, we should keep them in memory.

WRITE FOR US

READ NEXT

Published by

Published in

Haskell is an advanced purely-functional programming language. An open-source product of more than twenty years of cutting-edge research, it allows rapid development of robust, concise and correct software.