content: outer :: (a->b->c) -> [a] -> [b] -> [[c]]
  outer f [] _       = []
  outer f _ []       = []
  outer f (h1:t1) x2 = (f h1 <$> x2) : outer f t1 x2
  
  dot [] []           = 0
  dot (h1:t1) (h2:t2) = (h1*h2) + (dot t1 t2)
  
  transpose [] = []
  transpose ([] : xss) = transpose xss
  transpose ((x:xs) : xss)
    = (x : [h | (h:_) <- xss]) : transpose (xs : [ t | (_:t) <- xss])
  
  mul :: Num a => [[a]] -> [[a]] -> [[a]]
  mul a b = outer dot a (transpose b)
  
  delRow :: Int -> [a] -> [a]
  delRow i v =
    (first ++ rest) where (first, _:rest) = splitAt i v
  
  delCol :: Int -> [[a]] -> [[a]]
  delCol j m = (delRow j) <$> m
  
  -- Determinant:
  adj :: Num a => [[a]] -> [[a]]
  adj [] = []
  adj m =
    [
      [(-1)^(i+j) * det (delRow i $ delCol j m)
      | i <- [0.. -1+length m]
      ]
    | j <- [0.. -1+length m]
    ]
  det :: Num a => [[a]] -> a
  det [] = 1
  det m  = (mul m (adj m)) !! 0 !! 0
  
  -- Permanent:
  padj :: Num a => [[a]] -> [[a]]
  padj [] = []
  padj m =
    [
      [perm (delRow i $ delCol j m)
      | i <- [0.. -1+length m]
      ]
    | j <- [0.. -1+length m]
    ]
  perm :: Num a => [[a]] -> a
  perm [] = 1
  perm m  = (mul m (padj m)) !! 0 !! 0
  