Aşağıdakilerin tümüne sahip bir sistemi nasıl kurarım :
- Değişmez nesnelerle saf fonksiyonların kullanılması.
- Sadece ihtiyaç duyduğu işlevin bir işlev verilerine aktarın, daha fazla değil (yani büyük uygulama durumu nesnesi yok)
- İşlevler için çok fazla argüman bulundurmaktan kaçının.
- Fonksiyonlara çok fazla parametrenin aktarılmasını önlemek için, sadece işlevlere parametrelerin paketlenmesi ve paketlerinin açılması amacıyla yeni nesneler oluşturmaktan kaçının. Bir işleve tek bir nesne olarak birden çok öğe paketleyeceğim, bu nesnenin geçici olarak oluşturulmuş bir şey değil, söz konusu verilerin sahibi olmasını istiyorum
Bana öyle geliyor ki, Devlet monad kuralı 2 numaralı kuralı ihlal ediyor, ancak bu açık olmasa da, monad boyunca dokunmuş.
Lensleri bir şekilde kullanmam gerektiğini hissediyorum, ancak İşlevsel olmayan diller için çok az şey yazıldı.
Arka fon
Bir alıştırma olarak, var olan uygulamalarımdan birini nesne yönelimli bir stilden işlevsel bir stile dönüştürüyorum. Yapmaya çalıştığım ilk şey, uygulamanın iç çekirdeğini olabildiğince yapmak.
Duyduğum bir şey, "Devlet" i tamamen işlevsel bir dilde nasıl yöneteceğimi ve Devlet monadsları tarafından yapıldığına inandığım şey, mantıksal olarak, saf bir işlev olarak adlandırdığınız, dünya olduğu gibi ", sonra işlev geri döndüğünde, değiştikçe dünyanın durumuna geri döner.
Örnek olarak, "merhaba bir dünya" yı tamamen işlevsel bir şekilde yapma şekliniz, sanki ekranınızın bu durumunu programınıza aktarır ve üzerine "merhaba dünya" yazılı ekranın durumunu geri alırsınız. Yani teknik olarak, saf bir işlevi çağırıyorsunuz ve hiçbir yan etkisi yok.
Buna dayanarak başvurumu inceledim ve: 1. İlk olarak tüm uygulama durumumu tek bir global nesneye (GameState) koy 2. İkinci olarak GameState'i değişmez hale getirdim. Değiştiremezsiniz. Bir değişikliğe ihtiyacınız varsa, yeni bir değişiklik yapmanız gerekir. Bunu, isteğe bağlı olarak değişen bir veya daha fazla alanı alan bir kopya oluşturucu ekleyerek yaptım. 3. Her uygulamaya GameState'i parametre olarak iletiyorum. İşlev içinde, ne yapacağını yaptıktan sonra, yeni bir GameState oluşturur ve geri döndürür.
Nasıl saf bir fonksiyonel çekirdek ve dış GameState uygulamanın ana iş akışı döngü besleyen bir döngü var.
Benim sorum:
Şimdi, benim sorunum, GameState'in yaklaşık 15 farklı değişmez nesneye sahip olmasıdır. En düşük seviyedeki işlevlerin çoğu, puan tutma gibi bu nesnelerin yalnızca birkaçında çalışır. Diyelim ki skoru hesaplayan bir fonksiyonum var. Bugün, GameState yeni bir skorla yeni GameState oluşturarak skoru değiştiren bu fonksiyona aktarılıyor.
Bununla ilgili bir şeyler yanlış görünüyor. İşlev için GameState'in tamamı gerekmez. Sadece Score nesnesine ihtiyacı var. Bu yüzden Skoru geçmek ve sadece Skoru döndürmek için güncelledim.
Bu mantıklı görünüyordu, bu yüzden diğer işlevlerle daha ileri gittim. Bazı işlevler GameState'ten 2, 3 veya 4 parametre geçirmemi gerektiriyor, ancak deseni uygulamanın dış çekirdeğine kadar kullandığım için, uygulama durumunu giderek daha fazla geçiyorum. İş akışı döngüsünün en üstünde, bir yöntemi çağırırdım, bu yöntemi bir yöntemi çağıracak yöntemi çağırırdı, puanın hesaplandığı yere kadar. Bu, en alttaki bir fonksiyonun skoru hesaplayacağı için mevcut skorun tüm bu katmanlardan geçtiği anlamına gelir.
Şimdi bazen onlarca parametreyle fonksiyonum var. Parametrelerin sayısını azaltmak için bu parametreleri bir nesneye koyabilirim, ancak daha sonra, sadece geçmemek için sadece çağrı sırasında inşa edilen bir nesne yerine, bu sınıfın durum uygulama durumunun ana konumu olmasını isterim. birden çok parametrede ve ardından paketinden çıkarın.
Şimdi merak ediyorum, sorunum fonksiyonlarımın çok derin yuvalanmış mı? Bu, küçük işlevlere sahip olmak istemenin sonucudur, bu nedenle bir işlev büyüdüğünde yeniden düzenler ve birden çok küçük işleve bölerim. Ancak bunu yapmak daha derin bir hiyerarşi üretir ve dış işlev doğrudan bu nesneler üzerinde çalışmasa bile iç işlevlere iletilen herhangi bir şeyin dış işleve iletilmesi gerekir.
Bu sorundan kaçınan yol boyunca GameState'i geçmek gibi görünüyordu. Ama işleve ihtiyaç duyduğundan daha fazla bilgi aktarma konusundaki asıl probleme geri döndüm.