      Nothing -> (tileMatrix, edgeMap, found, tileMap)
      Just tile -> foldl (placeTile tileId coords) (tileMatrix, edgeMap, found, tileMap) (zip [STop, SRight, SBottom, SLeft] (tileToEdges tile))

    placeTile :: Int -> (Int, Int) -> (TileMatrix, EdgeMap, HS.HashSet Int, TileMap) -> (Side, (Int, Int64)) -> (TileMatrix, EdgeMap, HS.HashSet Int, TileMap)
    placeTile tileId coords (tileMatrix, edgeMap, found, tileMap) (side, (edge, edgeHash)) = fromMaybe (tileMatrix, edgeMap, found, tileMap) (do
      tileIds <- HM.lookup edgeHash edgeMap
      nextTileId <- find (/= tileId) (HS.toList tileIds)
      isFound <- checkSet nextTileId found