Circa la funzione di ricerca infinita:
C'è già una funzione che cerca una lista per un valore - elem
.
Se si presuppone che l'elenco infinito è ordinato, potremmo scrivere una versione di elem che funziona su tale elenco. Questo può essere facilmente eseguito rifiutando innanzitutto qualsiasi elemento inferiore al valore di ricerca. Il primo valore non rifiutato deve essere uguale o maggiore dell'elemento di ricerca. Se uguale - restituire true, altrimenti return false utilizzo
infiniteElem1 :: (Ord a) => a -> [a] -> Bool
infiniteElem1 x list = (== x) $ head $ dropWhile (< x) list
Esempio:
> infiniteElem1 10 [1..]
True
> infiniteElem1 10 [1,3..]
False
C'è un problema anche se con infiniteElem1
però: Se utilizzato in un elenco finito, può generare un'eccezione se l'elemento non è stato trovato:
> infiniteElem1 100 [1,2,3]
*** Exception: Prelude.head: empty list
Questa è una ragione per la funzione head
è meglio evitare.Una soluzione migliore è questa:
infiniteElem :: (Ord a) => a -> [a] -> Bool
infiniteElem x list = case dropWhile (< x) list of
[] -> False
(v:_) -> v == x
Ora funziona con un elenco ordinato finita così:
> infiniteElem 100 [1,2,3]
False
Con questo il problema diventa banale:
let isSquare n = n `infiniteElem` [ x * x | x <- [1..]]
fonte
2013-04-26 04:57:55
Y vuoi continuare a controllare il prossimo elemento nell'elenco fino al tuo numero/numero di lista <0 – Zyerah
Il problema è che 'sum' è rigoroso; consuma l'intera lista prima di tornare. Un modo per assicurarsi che la funzione si interrompa è fornirgli una lista finita: 'x <- [1..n]' testerà solo i numeri '<= n'. –
@Telthien - intendi <1? –