Требуется реализовать алгоритм Зейделя для решения СЛАУ. Хочу реализовать на Хаскеле. Я Хаскель только учу и уверен, что я всё сделал не так, как сделали бы нормальные люди. Прошу поправить.
Про метод Зейделя (из Канатников, Крищенко "Линейная алгебра"):
Если имеется СЛАУ 

, то мы сначала приводим её к нормальному виду 

, т. к. чтобы алгоритм сходился, нужно, чтобы 

 была положительно определённой и симметрической. 

 такой является, и если исходная СЛАУ имеет решение, то и нормальная СЛАУ будет иметь такое же. Пускай СЛАУ 

 уже нормальная. Тогда сам алгоритм:

где 

 -- число уравнений в СЛАУ. (В правой части есть 

, но когда считается 

, он уже подсчитан.)
(Код)
Код:
-- Тут можно не читать, я просто определяю некоторые матричные операции
type Vector = [Float]
type Matrix = [Vector]
infix 9 !
(!) :: Matrix -> (Int,Int) -> Float
m ! (i,j) = m !! (i-1) !! (j-1)
width :: Matrix -> Int
width m = length $ m !! 0
height :: Matrix -> Int
height = length
mul :: Matrix -> Matrix -> Matrix
mul a b | width a == height b =
    [[sum [a!(i,k) * b!(k,j) | k <- [1..n]] | j <- [1..n]] | i <- [1..m]]  where
        n = width a
        m = height b
transpose :: Matrix -> Matrix
transpose m = [[m!(i,j) | i <- [1..(height m)]] | j <- [1..(width m)]]
-- Вот сама функция решения СЛАУ
-- a', b' -- это матрицы A и b соответственно. n -- количество итераций (пока задаю сам).
solve :: Matrix -> Vector -> Int -> Vector
solve a' b' n | width a' == length b' = x n  where
    t = transpose a'    -- A^T
    a = t `mul` a'       -- A^T A
    b = (transpose $ mul t $ transpose [b']) !! 0      -- A^T b
    r = length b        -- n
    x 0 = replicate r 0
    x (n+1) = [(b!!(i-1) - sum [ a!(i,j) * (x (n+1))!!(j-1) | j <- [1..(i-1)]]
                - sum [ a!(i,j) * (x n)!!(j-1) | j <- [(i+1)..r]]) / a!(i,i)
              | i <- [1..r]]
Код работает:
Код:
-- {x+2y=4, 3x-4y=-2}, {x=1.2, y=1.4}
*Main> solve [[1,2],[3,-4]] [4,-2] 10
[1.1972656,1.3986328]
 Но очень медленно (уже для 

 и 

 в ghci работает несколько секунд). Наверное я неправильно подошёл к реализации функции 

. Она у меня сейчас возвращает список и, я боюсь, много раз вычисляется одно и то же. Была идея сделать бесконечный список решений 

, чтобы при вычислении 

 функция ссылаться к предыдущему элементу списка. Ничего не вышло  
