Ho un codice Haskell che fa funziona correttamente su una lista infinita, ma non capisco perché può farlo con successo. (Ho modificato il mio codice originale - che non ha gestito liste infinite - per incorporare qualcosa da qualche altro codice online, e improvvisamente vedo che funziona ma non so perché).Perché questo codice Haskell funziona correttamente con elenchi infiniti?
myAny :: (a -> Bool) -> [a] -> Bool
myAny p list = foldr step False list
where
step item acc = p item || acc
mia comprensione di foldr è che sarà un ciclo tra ogni elemento della lista (e forse che la comprensione è incompleta). Se è così, non dovrebbe importare come è formulata la funzione "step" ... il codice dovrebbe essere incapace di gestire loop infiniti.
Tuttavia, le seguenti opere:
*Main Data.List> myAny even [1..]
True
Si prega di aiutarmi a capire: perché ??
Inoltre è possibile verificare che il codice non calcoli più di 2 elementi con: 'myAny p list = foldr (\ ia -> trace (mostra i) (pi || a))' - che mostrerà solo '1 2 True' – viraptor
Wow, questa è stata una risposta di apertura MOLTO occhio. Prima di tutto, non ho iniziato con la definizione di foldr davanti a me. Ho pensato che il suo codice avrebbe utilizzato funzionalità avanzate che ancora non conosco, quindi l'ho visto solo come ultima risorsa. La tua risposta mi ha spinto a dare un'occhiata, e questo chiarisce molto. foldr stesso usa la ricorsione strutturale "normale". Adoro il modo in cui l'hai rotto. Grazie. –
BTW, è il || completamente severo nel suo primo argomento o semplicemente "dare la preferenza" al suo primo argomento? Ad esempio, cosa succede se Arg 2 era già stato valutato, ma Arg 1 era ancora solo un thunk? E dire che Arg 2 era falso. Has Haskell avrebbe cortocircuito nella direzione opposta? Grazie. –