Nasıl bu işlevi fibonacci memoized?
Ne mekanizması tarafından bu fonksiyon fibonacci memoized?
fib = (map fib' [0..] !!)
where fib' 1 = 1
fib' 2 = 1
fib' n = fib (n-2) fib (n-1)
İlgili bir kayda göre, neden bu sürümü değil mi?
fib n = (map fib' [0..] !! n)
where fib' 1 = 1
fib' 2 = 1
fib' n = fib (n-2) fib (n-1)
CEVAP
Haskell değerlendirme mekanizmasıdır-gerek: bir değer gerektiğinde hesaplanır ve tekrar sordu ihtimaline karşı hazır tuttu. Eğer biz bazı tanımlama listesi xs=[0..]
ve daha sonra sormak için 100 öğe xs!!99
100 yuvasına listesini alır "etli", holding sayısı 99
Şimdi, hazır bir sonraki erişim.
Bu ne hiledir, "a-listesi-ile-gidiyor", istismar. İki kat-recursve tanımı Fibonacci normal, fib n = fib (n-1) fib (n-2)
, kendisi işlevi, iki kez üst üstel patlamaya neden çağrılır. Ama bu hile ile, geçici sonuçlar için bir liste hazırladık ve git "listesinde":
fib n = (xs!!(n-1)) (xs!!(n-2)) where xs = 0:1:map fib [2..]
Hile bu liste oluşturulmuş almak için neden, ve bu liste uzak (çöp toplama) fib
çağrılar arasında gidip neden olur. Bunu başarmak için en kolay yoluadıo liste.Eğer bunun adı "eğer kalacak."
İlk sürümü bir monomorphic sabit tanımlar, ve ikinci adında bir işlevi tanımlar. Polimorfik bir işlevi, yani hizmet etmek gerekebilir farklı türleri için aynı iç liste kullanabilirsinizpaylaşım yokyani hiçbir memoization.
İlk sürümü ile, derleyici ediliyorcömertbizimle sürekli ifadeyi (map fib' [0..]
) ve ayrı paylaşılabilir bir varlık yapma ama bunu yapmak için herhangi bir yükümlülük altında değil.ve biz aslında durum vardıryoko bizim için bunu otomatik olarak yapmak istiyorum.
(düzenleme:Bu yeniden yazma düşünün:
fib1 = f fib2 n = f n fib3 n = f n
where where where
f i = xs !! i f i = xs !! i f i = xs !! i
xs = map fib' [0..] xs = map fib' [0..] xs = map fib' [0..]
fib' 1 = 1 fib' 1 = 1 fib' 1 = 1
fib' 2 = 1 fib' 2 = 1 fib' 2 = 1
fib' i=fib1(i-2) fib1(i-1) fib' i=fib2(i-2) fib2(i-1) fib' i=f(i-2) f(i-1)
Gerçek hikayesini iç içe kapsam tanımlar. 1. tanımı ile dış kapsam yok, ve 3 dış-kapsam araması için dikkatli fib3
ama aynı düzey f
.
fib2
her yeni çağırma hiçbirini yeniden çünkü iç içe tanımları oluşturma gibi görünüyorolabilir(teoride) farklı şekilde tanımlanmışgören
değeri (Vitus ve bunu belirttiğin için Tikhon için teşekkürler). İlk Definition yok n
bağlı ve birlikte üçüncü bir bağımlılık, ama her biri ayrı çağrı için fib3
çağrıları f
dikkatli sadece arama tanımları aynı düzey kapsamı, iç bu özel çağırma fib3
, aynı xs
alır devşirme (yani paylaşımlı) için çağırma fib3
.
Ama hiçbir şey yukarıdaki sürümleri herhangi bir iç tanımları aslında tanımaktan derleyici önleyenbağımsızn
dış bağlama, sonuçta lambda lifting tam memoization sonuçlanan gerçekleştirmek için (polimorfik tanımları hariç). Aslında bu monomorphic türleri ile ilan ve O2 bayrağı ile derlenmiş, tüm üç sürümleri ile olmuyor tam olarak. Polimorfik tür bildirimleri, fib3
sergiler yerel paylaşım ve fib2
ile paylaşım yok.
Sonuçta, bağlı olarak bir derleyici ve derleyici en iyi duruma getirme kullanılır ve nasıl test (yükleme dosyaları GHCİ, derlenmiş ya da değil,- O2 ya da değil, ya da tek başına), ve ister alır bir monomorphic veya bir polimorfik tür davranışları olabilir değişimin olup olmadığı sergiler yerel (per-der) paylaşımı (yani doğrusal zaman her çağrı), memoization (yani doğrusal zaman İlk Çağrı ve 0 kez izleyen çağrılarda ile aynı ya da daha küçük bağımsız değişken), ya da paylaşım yok (üstel zaman).
Kısa cevap, derleyici bir şey vardır. :)
Nasıl JavaScript arayan işlevi öğreneb...
Nasıl türetilmiş sınıf, üst sınıf bir ...
Nasıl bir işlevi jQuery bir iletişim k...
Nasıl bir bash işlevi, bir dize değeri...
Nasıl dize için bir PHP işlevi bir Değ...