Real World Haskell, capitolo 4, pagina 98 della stampa chiede se words
può essere implementato usando le pieghe, e anche questa è la mia domanda:
È possibile? Se no, perché? Se lo è, come?
Ho trovato quanto segue, che si basa sull'idea che ogni non spazio dovrebbe essere anteposto all'ultima parola nell'elenco di output (ciò accade nella otherwise
protezione) e che uno spazio dovrebbe innescare l'aggiunta di una parola vuota a l'elenco di output se non ce n'è già uno (questo è gestito in if
- then
- else
).
myWords :: String -> [String]
myWords = foldr step [[]]
where
step x yss@(y:ys)
| x == ' ' = if y == "" then yss else "":yss
| otherwise = (x:y):ys
Chiaramente questa soluzione è sbagliata, poiché gli spazi iniziali nella stringa di input generano una stringa vuota iniziale nell'elenco di stringhe di output.
Al link sopra, ho esaminato alcune delle soluzioni proposte per altri lettori e molte di loro funzionano in modo simile alla mia soluzione, ma generalmente "post-processano" l'output del fold, ad esempio tail
inserendolo se è una stringa iniziale vuota.
Altri approcci usano tuple (in realtà solo coppie), in modo che la piega si occupi della coppia e possa gestire bene gli spazi iniziali / finali.
In tutti questi approcci, foldr
(o un'altra piega, prima) non è la funzione che fornisce l'output finale fuori dalla scatola; c'è sempre qualcos'altro che deve regolare l'output in qualche modo.
Quindi torno alla domanda iniziale e chiedo se è effettivamente possibile implementare words
(in modo che gestisca correttamente gli spazi finali / iniziali / ripetuti) usando le pieghe. Usando le pieghe intendo che la funzione di piegatura deve essere la funzione più esterna:
myWords :: String -> [String]
myWords input = foldr step seed input