Tutte le funzioni del modulo Enum sono eager. Quando esegui più operazioni sugli enumerabili con il modulo Enum, ogni operazione genera un risultato intermedio.
Il modulo Stream è un'alternativa lazy al modulo Enum, che è eager. Offre molte delle stesse funzioni di Enum, ma invece di generare risultati intermedi costruisce una serie di calcoli che vengono eseguiti solo quando lo stream viene passato a una funzione del modulo Enum.
Gli stream implementano il Enumerable protocollo e sono componibili: puoi concatenarli tra loro per creare funzionalità più complesse.
Sei un grande fan del canale YouTube Numberphile e hai appena visto un video interessante sulla sequenza dei numeri di Lucas. Vuoi creare questa sequenza usando Elixir.
Mentre progetti la funzione, vuoi sfruttare la valutazione pigra: così puoi generare tutti i numeri che vuoi, ma solo quando ti servono. Per questo decidi di usare uno stream.
Aggiungi una guard clause per sollevare un errore se si prova a generare la sequenza con un valore non intero o con un intero minore di 1. Farlo come primo passo eviterà bug di ricorsione infinita nei passi successivi.
LucasNumbers.generate("Hello World")
# => ** (ArgumentError) count must be specified as an integer >= 1
Sai che la sequenza ha due numeri iniziali che non seguono la stessa regola. Scrivi due clausole per i casi base che restituiscano questi numeri:
LucasNumbers.generate(1)
# => [2]
LucasNumbers.generate(2)
# => [2, 1]
Per qualsiasi sequenza più lunga di 2, sai che devi sommare i due numeri precedenti per ottenere il numero successivo, e così via. Scrivi il caso generalizzato.
LucasNumbers.generate(3)
# => [2, 1, 3]
LucasNumbers.generate(4)
# => [2, 1, 3, 4]
Iscriviti a Exercism per imparare e padroneggiare Elixir con 58 concetti168 esercizi e il mentoring di persone reali, tutto gratis.