arantía de optimización de cola: codificación de bucle en Haskell

Así que la versión corta de mi pregunta es, ¿cómo se supone que codifiquemos los bucles en Haskell?en genera? No hay garantía de optimización de cola en Haskell, los patrones de explosión ni siquiera son parte del estándar (¿verdad?), Y el paradigma de plegar / desplegar esn garantizado para trabajar en toda situación. Aquí estácaso en punt fueron solo patrones de explosión que me ayudaron a hacer que funcionara en un espacio constante (ni siquiera usando$! ayudó ... aunquela prueb se realizó en Ideone.com que utiliza ghc-6.8.2).

Se trata básicamente de un bucle anidado, que en el paradigma de lista se puede establecer como

prod (sum,concat) . unzip $ 
    [ (c, [r | t]) | k<-[0..kmax], j<-[0..jmax], let (c,r,t)=...]
prod (f,g) x = (f.fst $ x, g.snd $ x)

O en seudocódigo:

let list_store = [] in
for k from 0 to kmax
    for j from 0 to jmax
        if test(k,j) 
            list_store += [entry(k,j)]
        count += local_count(k,j)
result = (count, list_store)

Hasta que le agregué el patrón de explosión, obtuve una pérdida de memoria o incluso un desbordamiento de pila. Pero los patrones de explosión no son parte del estándar, ¿verdad? Entonces la pregunta es,cóm es uno para codificar lo anterior, en Haskell estándar, para ejecutar en espacio constante?

Aquí estáel código de prueba. El cálculo es falso, pero los problemas son los mismos. @EDITAR Losfoldrl código formulado en @ es:

testR m n = foldr f (0,[]) 
               [ (c, [(i,j) | (i+j) == d ])
                 | i<- [0..m], j<-[0..n], 
                   let c = if (rem j 3) == 0 then 2 else 1 ]
  where d = m + n - 3
    f (!c1, [])     (!c, h) = (c1+c,h) 
    f (!c1, (x:_))  (!c, h) = (c1+c,x:h)

Intentando ejecutar print $ testR 1000 1000 produce desbordamiento de pila. Cambiando afoldl solo tiene éxito si usa patrones de explosión enf, pero construye la lista en orden inverso. Me gustaría construirlo perezosamente y en el orden correcto. ¿Se puede hacer con cualquier tipo defold, Para elidiomátic solución?

EDITAR para resumir la respuesta que obtuve de @ehird: no hay nada que temer usando el patrón de explosión. Aunque no está en Haskell estándar, se codifica fácilmente comof ... c ... = case (seq c False) of {True -> undefined; _ -> ...}. La lección es que solo la coincidencia de patrones fuerza un valor, yseq haceN fuerza cualquier cosa por sí mismo, sino que organiza quecuand seq x y es forzado - por una coincidencia de patrón -x será forzado también, yy será la respuesta. Al contrario de lo que pude entender del Informe en línea,$! haceN forzar algo por sí mismo, aunquee llamado a "operador de aplicación estricto".

Y el punto de @stephentetley -rigo es muy importante para controlar el comportamiento espacial. Por lo tanto, está perfectamente bien codificar bucles en Haskell con el uso adecuado de anotaciones de rigor con patrones de explosión, donde sea necesario, para escribir cualquier tipo de función de plegado especial (es decir, que consuma estructura) que se necesita, como terminé haciendo en primer lugar - y confíe en GHC para optimizar el código.

Muchas gracias a todos por vuestra ayuda.

Respuestas a la pregunta(4)

Su respuesta a la pregunta