Öğreniyorum OCaml. Biliyorum ki OCaml, hem zorunlu programlama tarzı hem de işlevsel programlamayı sağlıyor. aşağıdaki gibi OCaml'de Memoisation ve Bir Referans Listesi
Ben fonksiyonufibonacci1
standart şekillerde uygulanmaktadır OCaml
let memoise f =
let table = ref []
in
let rec find tab n =
match tab with
| [] ->
let v = (f n)
in
table := (n, v) :: !table;
v
| (n', v) :: t ->
if n' = n then v else (find t n)
in
fun n -> find !table n
let fibonacci2 = memoise fibonacci1
yılında n'inci Fibonacci sayı hesaplamak için benim tabii bir parçası olarak bu kodun rastladım:
let rec fibonacci1 n =
match n with
| 0 | 1 -> 1
| _ -> (fibonacci1 (n - 1)) + (fibonacci1 (n - 2))
Şimdi sorum şu: fibonacci2'de nasıl hatıralara ulaşıyoruz. Fibonacci2 fonksiyonu içinde table
tanımlanmıştır ve bu nedenle, mantığım, fonksiyonun hesaplaması bittikten sonra table
listesinin kaybolması gerektiğini ve her aramadan sonra tablonun tekrar tekrar üretileceğini belirtir.
OCaml REPL'de iki kez fibonacci 35
işlevini çağırdığım basit bir sınama çalıştım ve ikinci işlev çağrısı, yanıtı işlevimin ilk çağrısından (beklentilerimin aksine) önemli ölçüde daha hızlı döndürdü.
ref
kullanarak bir değişken bildirmek, varsayılan olarak genel bir kapsam verirse bu mümkün olabilir.
let f y = let x = ref 5 in y;;
print_int !x;;
çalıştı Ama bu bana x'in değeri sınırsız olduğunu belirten bir hata verdi.
Bu neden böyle davranıyor?
Döndüğünüz değerin, 'f' bir işlev olduğunu ama sonra değerin bir kısmı tablonun olduğunu da söylüyorsunuz. Bunun ne anlama geldiğinden emin değilim. –
Bir işlev, işlevin tüm serbest değişkenlerinin (işlevde tanımlanmayan tüm adların) değerleri ile kapatılır. Öyleyse, bir işlev (ya da bir kapanış gerçekten) içinde özünde keyfi şeylere sahip olabilir. 'Memoise' tarafından döndürülen kapanış, içindeki tabloya sahiptir. –