Jak zauważył @KarlBielefeldt, funkcjonalnym podejściem do takiego problemu jest postrzeganie go jako powrotu do nowego stanu z poprzedniego stanu. Same funkcje nie przechowują żadnych informacji, dlatego zawsze aktualizują stan m do stanu n .
Myślę, że uważasz to za nieskuteczne, ponieważ zakładasz, że poprzedni stan musi być przechowywany w pamięci podczas obliczania nowego stanu. Zauważ, że wybór pomiędzy pisaniem całkowicie nowego stanu a ponownym pisaniem starego na miejscu jest szczegółem implementacji z punktu widzenia funkcjonalnego języka.
Powiedzmy na przykład, że mam listę milionów liczb całkowitych i chcę zwiększyć dziesiątą o jedną jednostkę. Kopiowanie całej listy z nowym numerem na dziesiątej pozycji jest marnotrawstwem, masz rację; ale jest to tylko koncepcyjny sposób opisania operacji kompilatorowi języka lub tłumaczowi. Kompilator lub interpreter może pobrać pierwszą listę i po prostu nadpisać dziesiątą pozycję.
Zaletą opisania operacji w ten sposób jest to, że kompilator może uzasadnić sytuację, gdy wiele wątków chce zaktualizować tę samą listę w różnych pozycjach. Jeśli operacja jest opisana jako „przejdź do tej pozycji i nadpisz to, co znalazłeś”, to programista, a nie kompilator, jest odpowiedzialny za to, aby nadpisania nie kolidowały.
Biorąc to wszystko pod uwagę, nawet w Haskell istnieje monada stanowa, która pomaga modelować sytuacje, w których „utrzymywanie stanu” jest bardziej intuicyjnym rozwiązaniem problemu. Ale proszę również zauważyć, że niektóre problemy, które uważasz za „z natury stanowe, jak pisanie do bazy danych ” mają niezmienne rozwiązania, takie jak Datomic . Może to być zaskakujące, dopóki nie zrozumiesz, że jest to koncepcja, niekoniecznie jej realizacja.