部分行列の列挙

http://karetta.jp/article/blog/oneline/011153から。

*Main> allSubs $ matrix 3 3
[[[1]],[[1,2]],[[1,2,3]],[[2]],[[2,3]],[[3]],[[1],[4]],[[1,2],[4,5]],[[1,2,3],[4,5,6]],[[2],[5]],[[2,3],[5,6]],[[3],[6]],[[1],[4],[7]],[[1,2],[4,5],[7,8]],[[1,2,3],[4,5,6],[7,8,9]],[[2],[5],[8]],[[2,3],[5,6],[8,9]],[[3],[6],[9]],[[4]],[[4,5]],[[4,5,6]],[[5]],[[5,6]],[[6]],[[4],[7]],[[4,5],[7,8]],[[4,5,6],[7,8,9]],[[5],[8]],[[5,6],[8,9]],[[6],[9]],[[7]],[[7,8]],[[7,8,9]],[[8]],[[8,9]],[[9]]]
matrix row col = [[(col * (y - 1)) + x| x <- [1..col]] | y <- [1..row]]

allSubs xss = let (x:xs) = map ((map (flip (:) [])) . fst . scan) xss
              in concat $ exec x xs
    where exec x [] = [x]
          exec x xs@(y:ys) = (scanl (zipWith (++)) x xs) ++ (exec y ys)


scan [x] = ([[x]],[[x]])
scan (x:xs) = (cur ++ ys,cur)
    where (ys,zs) = scan xs
          cur = [x]:(map (x :) zs)