Como señaló @KarlBielefeldt, el enfoque funcional para tal problema es verlo como un nuevo estado de un estado anterior. Las funciones en sí no contienen ninguna información, por lo que siempre actualizarán el estado m al estado n .
Creo que esto le parece ineficiente porque supone que el estado anterior debe mantenerse en la memoria mientras se calcula el nuevo estado. Tenga en cuenta que la elección entre escribir un estado completamente nuevo o reescribir el antiguo en su lugar es un detalle de implementación desde el punto de vista de un lenguaje funcional.
Por ejemplo, supongamos que tengo una lista de un millón de enteros y quiero aumentar la décima en una unidad. Copiar toda la lista con un nuevo número en su décima posición es un desperdicio, tiene razón; pero es solo la forma conceptual de describir la operación al compilador o intérprete de lenguaje. El compilador o intérprete es libre de tomar la primera lista y simplemente sobrescribir la décima posición.
La ventaja de describir la operación de esta manera es que el compilador puede razonar sobre la situación en la que muchos hilos quieren actualizar la misma lista en diferentes posiciones. Si la operación se describe como "vaya a esta posición y sobrescriba lo que encuentre", entonces es el programador, no el compilador, quien se encarga de asegurarse de que las sobrescrituras no colisionen.
Dicho todo esto, incluso en Haskell hay una mónada estatal que ayuda a modelar situaciones en las que "mantener el estado" es una solución más intuitiva para un problema. Pero también tenga en cuenta que algunos problemas que encuentra " intrínsecamente con estado, como escribir en una base de datos " tienen soluciones inmutables como Datomic . Esto puede ser sorprendente hasta que comprenda que es un concepto, no necesariamente su realización.