Using Data.Array to solve Sierpinski in Haskell
// is best called with one bulk list because each call incurs one O(n) array copy.

Folds over iterates when you need an index and know its range, it's like for vs. while.

drawCanvas :: Canvas -&gt; IO ()
drawCanvas = putStrLn . unlines . map (map snd)
  . DL.groupBy ((==) `DF.on` fst . fst) . DA.assocs

mkSierpinski :: Int -&gt; Int -&gt; Canvas
mkSierpinski maxLevel sierLevel = emptyCanvas maxLevel DA.//
  [ ((r+h, j), '1')
  | maxLevel &gt;= sierLevel
  , (r, c) &lt;- DF.foldrM split (0, 0) [maxLevel-sierLevel+1..maxLevel]
  , h &lt;- [0..2^(maxLevel-sierLevel)-1]
  , j &lt;- [c-h..c+h]
  ]