Práctico 3, Ejercicio 8

Práctico 3, Ejercicio 8

de Nicolas Grosso San Roman -
Número de respuestas: 1

Hola! 

No me doy cuenta de una mejora sustancial al hacer elem con foldr y foldl. Es más, creo que me tardan lo mismo aprox. Estuve pensando por qué foldl puede ser más eficiente, y sobre todo en el caso de 1 en [1..10000000], pues foldl comienza del inicio de la lista donde ya se encuentra 1. Sin embargo, veo que tanto foldl como foldr recorren toda la lista, aunque hayan dado con el resultado antes de que termine la recursión.

Quería saber qué tal estaba mi razonamiento y en qué le erro. Les dejo mis implementaciones, las cuales son prácticamente iguales.




Agradezco cualquier comentario, saludos!

En respuesta a Nicolas Grosso San Roman

Re: Práctico 3, Ejercicio 8

de Marcos Viera - InCo -
Hola,

El problema es que justamente las implementaciones son demasiado iguales, y en este caso el foldr no puede aprovechar la evaluación perezosa (o corto-circuito en términos de P1) del operador (||).
Recordemos que el comportamiento de foldr es: foldr f v [x1,x2,...,xn] ~>* f x1 (f x2 (... (f xn v)))
entonces en tu caso, como en tu f el resultado de la llamada recursiva lo ponés a la izquierda del ||, te quedaría algo como:
(((...||3==1))||(2==1)) || (1==1), donde tenés que resolver toda la subexpresión izquierda (que implica recorrer toda la lista) antes de saber que es True porque (1==1).

si en tu implementación definís:
f x res = x==a || res
entonces sí tendrías algo del estilo: (1==1) || ((2==1) || ((3==1) || ..))
que corta al encontrarse conque (1==1) es True.

saludos