import Ratio gaussStep :: [[Rational]] -> [[Rational]] gaussStep (x:xs) = x : (map (\l -> zipWith (\a b -> b - (head l) * a) (map (/ head x) x) l) xs) findAndReplace :: (a -> Bool) -> a -> [a] -> [a] -> [a] findAndReplace p l (x:xs) result | p x = x : result ++ [l] ++ xs | otherwise = findAndReplace p l xs $ result ++ [x] gaussSwap :: [[Rational]] -> [[Rational]] gaussSwap (x:xs) = findAndReplace (\x -> head x /= 0) x xs [] rationalGaussDet :: [[Rational]] -> Rational rationalGaussDet [[]] = 0 rationalGaussDet [[x]] = x rationalGaussDet m@(x:xs) | map head m == replicate (length m) 0 = 0 | head x == 0 = (toRational 0) - (rationalGaussDet $ gaussSwap m) | otherwise = (head x) * rationalGaussDet (minor 0 (gaussStep m)) gaussDet :: (Real a) => [[a]] -> Rational gaussDet m = rationalGaussDet (map (map toRational) m)