Tengo un código de Haskell que funciona funciona correctamente en una lista infinita, pero no entiendo por qué puede hacerlo con éxito. (Modifiqué mi código original, que no manejaba listas infinitas, para incorporar algo de otro código en línea, y de repente veo que funciona pero no sé por qué).¿Por qué este código Haskell funciona correctamente con listas infinitas?
myAny :: (a -> Bool) -> [a] -> Bool
myAny p list = foldr step False list
where
step item acc = p item || acc
Mi comprensión de foldr es que hará un bucle a través de cada elemento de la lista (y tal vez que la comprensión es incompleta). Si es así, no debería importar cómo se redacte la función "paso" ... el código no debería ser capaz de manejar bucles infinitos.
Sin embargo, las siguientes obras:
*Main Data.List> myAny even [1..]
True
Por favor, me ayudan a entender: ¿por qué ??
Además, puede verificar que el código no calcule más de 2 elementos con: 'myAny p list = foldr (\ ia -> trace (show i) (pi || a))' - que mostrará solo '1 2 True' – viraptor
Guau, esta ha sido una respuesta MUY llamativa. Antes que nada, no comencé con la definición de foldr en frente de mí. Supuse que su código usaría funciones avanzadas que aún no conozco, así que solo lo consideraría como último recurso. Tu respuesta me impulsó a echar un vistazo, y eso aclara mucho. foldr en sí mismo está utilizando la recursión estructural "simple viejo". Me encanta la forma en que lo rompiste. Gracias. –
BTW, es el || completamente estricto en su primera arg, o simplemente "da preferencia a" su primer arg? Por ejemplo, ¿qué pasaría si arg 2 ya hubiera sido evaluado, pero arg 1 todavía era solo un thunk? Y decir arg 2 era falso. ¿Hasckell cortocircuito en la dirección opuesta? Gracias. –