Real World Haskell, chapitre 4, page 98 de l'impression demande si words
peut être implémenté en utilisant des plis, et c'est aussi ma question:
C'est possible? Sinon, pourquoi? Si c'est le cas, comment?
J'ai trouvé ce qui suit, qui est basé sur l'idée que chaque non-espace doit être ajouté au dernier mot de la liste de sortie (cela se produit dans la otherwise
garde), et qu'un espace doit déclencher l'ajout d'un mot vide à la liste de sortie s'il n'y en a pas déjà une (elle est gérée dans le 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
Clairement, cette solution est fausse, car les espaces de tête dans la chaîne d'entrée entraînent une chaîne vide de tête dans la liste de sortie des chaînes.
Au lien ci-dessus, j'ai examiné plusieurs des solutions proposées pour d'autres lecteurs, et beaucoup d'entre elles fonctionnent de manière similaire à ma solution, mais elles "post-traitent" généralement la sortie du pli, par exemple en l' tail
intégrant s'il y a est une chaîne de début vide.
D'autres approches utilisent des tuples (en fait juste des paires), de sorte que le pli traite de la paire et peut bien gérer les espaces de début / fin.
Dans toutes ces approches, foldr
(ou un autre pli, fwiw) n'est pas la fonction qui fournit la sortie finale hors de la boîte; il y a toujours quelque chose d'autre à régler d'une manière ou d'une autre sur la sortie.
Par conséquent, je reviens à la question initiale et demande s'il est réellement possible d'implémenter words
(de manière à ce qu'il gère correctement les espaces de fin / de début / répétés) à l'aide de plis. En utilisant des plis, je veux dire que la fonction de pliage doit être la fonction la plus externe:
myWords :: String -> [String]
myWords input = foldr step seed input