The following code I devised to compute a determinant:
module MatrixOps where
determinant :: (Num a, Fractional a) => [[a]] -> a
determinant [[x]] = x
determinant mat =
sum [s*x*(determinant (getRest i mat)) | i <- [0..n-1], let x = (head mat) !! i
s = (-1)^i]
where n = length $ head mat
getRest :: (Num a, Fractional a) => Int -> [[a]] -> [[a]]
getRest i mat = removeCols i (tail mat)
removeCols :: (Num a, Fractional a) => Int -> [[a]] -> [[a]]
removeCols _ [] = []
removeCols i (r:rs) = [r !! j | j <- [0..n-1], j /= i] : removeCols i rs
where n = length r
I have a few general questions about the style of my code and practices:
Is a very "Haskell" solution? I come from an OOP background and I am still learning functional programming.
Is there a better way to space this out? I feel like some of the code is not very readable (this may just be because I am new), especially the definition of
determinant mat = ...
Is this code considerably "clean?"