Estoy trabajando en el problema 14 de Project Euler. Aquí está mi solución.¿Por qué esta expresión de Haskell es tan lenta?
import Data.List
collatzLength :: Int->Int
collatzLength 1 = 1
collatzLength n | odd n = 1 + collatzLength (3 * n + 1)
| even n = 1 + collatzLength (n `quot` 2)
maxTuple :: (Int, Int)->(Int, Int)->Ordering
maxTuple (x1, x2) (y1, y2) | x1 > y1 = GT
| x1 < y1 = LT
| otherwise = EQ
estoy ejecutando el siguiente de GHCi
maximumBy maxTuple [(collatzLength x, x) | x <- [1..1000000]]
Sé que si Haskell evaluado rigurosamente, el tiempo en esto sería algo así como O (n). Sin embargo, dado que Haskell evalúa perezosamente, parece que debería ser un múltiplo constante de n. Esto ha estado funcionando por casi una hora ahora. Parece muy irrazonable. ¿Alguien tiene alguna idea de por qué?
no veo la razón por la pereza de Haskell debe hacer ninguna diferencia a la complejidad de este algoritmo. – sepp2k
Su función 'collatzLength' no es recursiva de cola. Esto ralentiza la función y causa una asignación innecesaria. Y su 'maxTuple' es lo mismo que' comparando fst'. – fuz
@sepp Realmente no sé cómo se implementan las Comprensiones de listas. Si están usando Map, si Haskell evaluó estrictamente, parece que debería pasar por la lista varias veces. –