Conways game of life in Haskell
A few things which came to my mind while reading your code:


The Show instance for CellState might be a bit nicer by not writing out the case expression manually but rather using

instance Show CellState where
    show Dead  = "_"
    show Alive = "#"

You could shorten initializeGrid by using mapM_:

initializeGrid :: GridState ()
initializeGrid = mapM_ (\(x, y) -&gt; setPositionToColor x y Alive)
    [(0,0),(1,1),(1,2),(2,0),(2,1),(4,4),(5,4),(6,4),(5,5),(5,4),(5,6)]

take n [0,1..] is the same as [0,1..n] (looking at createGrid).
callCellState could be shortened by only explicitely testing the conditions determining whether the cell becomes (or remains) alive:

calcCellState :: Bool -&gt; Int -&gt; CellState
calcCellState living livingNeighbours
    | living &amp;&amp; livingNeighbours `elem` [2,3] = Alive
    | not living &amp;&amp; livingNeighbours == 3     = Alive
    | otherwise                               = Dead



On a more general note, seeing how long the updateCell function is and how you had to roll your own next and previous function I do suspect that lists are not the most appropriate data structure for this kind of problem. A vector may be easier to work with.