Real World Haskell, capítulo 4, página 98 de la impresión pregunta si words
se puede implementar usando pliegues, y esta es mi pregunta también:
¿Es posible? Si no, ¿por qué? Si es así, ¿cómo?
Se me ocurrió lo siguiente, que se basa en la idea de que cada espacio que no sea espacio debe anteponerse a la última palabra en la lista de salida (esto sucede en la otherwise
guardia), y que un espacio debe activar la adición de una palabra vacía a la lista de salida si aún no hay una (esto se maneja en el 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
Claramente, esta solución es incorrecta, ya que los espacios iniciales en la cadena de entrada dan como resultado una cadena vacía inicial en la lista de cadenas de salida.
En el enlace de arriba, he examinado varias de las soluciones propuestas para otros lectores, y muchas de ellas funcionan de manera similar a mi solución, pero generalmente "procesan posteriormente" la salida del pliegue, por ejemplo tail
, si la hay es una cadena inicial vacía.
Otros enfoques usan tuplas (en realidad solo pares), de modo que el pliegue trata con el par y puede manejar bien los espacios iniciales / finales.
En todos estos enfoques, foldr
(u otro pliegue, fwiw) no es la función que proporciona la salida final de la caja; siempre hay algo más que tiene que ajustar la salida de alguna manera.
Por lo tanto, vuelvo a la pregunta inicial y pregunto si es realmente posible implementar words
(de una manera que maneje correctamente los espacios finales / iniciales / repetidos) usando pliegues. Al usar pliegues quiero decir que la función de plegado tiene que ser la función más externa:
myWords :: String -> [String]
myWords input = foldr step seed input