Seperti dicatat oleh @KarlBielefeldt, pendekatan fungsional untuk masalah seperti itu adalah melihatnya mengembalikan negara baru dari keadaan sebelumnya. Fungsi itu sendiri tidak menyimpan informasi apa pun, sehingga mereka akan selalu memperbarui status m ke status n .
Saya pikir Anda menemukan ini tidak efisien karena Anda menganggap keadaan sebelumnya harus disimpan dalam memori saat menghitung keadaan baru. Perhatikan bahwa pilihan antara menulis keadaan yang sama sekali baru atau menulis ulang yang lama di tempat adalah detail implementasi dari sudut pandang bahasa fungsional.
Misalnya, saya memiliki daftar sejuta bilangan bulat, dan ingin menambah kesepuluh dengan satu unit. Menyalin seluruh daftar dengan nomor baru di posisi kesepuluh adalah pemborosan, Anda benar; tetapi hanya cara konseptual untuk menggambarkan operasi ke kompiler bahasa atau juru bahasa. Kompiler atau juru bahasa bebas untuk mengambil daftar pertama dan hanya menimpa posisi kesepuluh.
Keuntungan dari menggambarkan operasi dengan cara ini adalah bahwa kompiler dapat mempertimbangkan situasi ketika banyak utas ingin memperbarui daftar yang sama pada posisi yang berbeda. Jika operasi digambarkan sebagai "buka posisi ini dan timpa apa yang Anda temukan", maka itu adalah programmer, bukan kompiler, yang bertugas memastikan bahwa overwrites tidak bertabrakan.
Dengan semua yang dikatakan, bahkan di Haskell ada monad negara yang membantu memodelkan situasi di mana "menjaga negara" adalah solusi yang lebih intuitif untuk masalah. Tetapi tolong perhatikan juga beberapa masalah yang Anda temukan " secara inheren stateful, seperti menulis ke database " memiliki solusi yang tidak dapat diubah seperti Datomic . Ini bisa mengejutkan sampai Anda memahaminya adalah sebuah konsep, belum tentu realisasinya.