Bu, haritaları ve kıvrımları açıklamaya yardımcı olacak ek bir cevaptır. Aşağıdaki örnekler için bu listeyi kullanacağım. Unutmayın, bu liste değişmez, bu yüzden asla değişmeyecek:
var numbers = [1, 2, 3, 4, 5]
Örneklerimde sayılar kullanacağım çünkü okunması kolay kodlara yol açıyorlar. Bununla birlikte, kıvrımların geleneksel bir zorunluluk döngüsünün kullanılabileceği her şey için kullanılabileceğini unutmayın.
Bir harita şeyin bir listesini ve bir işlev alır ve işlevini kullanarak modifiye edilmiş bir listesini döndürür. Her öğe işleve iletilir ve işlevin döndürdüğü her şey olur.
Bunun en kolay örneği, listedeki her sayıya bir sayı eklemektir. Dili agnostik hale getirmek için sözde kod kullanacağım:
function add-two(n):
return n + 2
var numbers2 =
map(add-two, numbers)
Yazdırdıysanız numbers2
, [3, 4, 5, 6, 7]
her bir öğeye 2 eklenmiş ilk listenin hangisi olduğunu görürsünüz . Fonksiyonun kullanımına add-two
verildiğine dikkat edin map
.
Kapaklar benzerdir, ancak onlara vermeniz gereken işlev 2 bağımsız değişken almalıdır. İlk argüman genellikle akümülatördür (en yaygın olan sol katta). Akümülatör, döngü sırasında geçirilen verilerdir. İkinci argüman listenin geçerli öğesidir; tıpkı map
fonksiyon için yukarıdaki gibi .
function add-together(n1, n2):
return n1 + n2
var sum =
fold(add-together, 0, numbers)
Yazdırdıysanız sum
, sayı listesinin toplamını görürsünüz: 15.
İşte argümanların yapması fold
gerekenler:
Bu, verdiğimiz işlevdir. Kapak, geçerli akümülatör işlevini ve listenin geçerli öğesini geçirir. Fonksiyonun geri dönüşü ne olursa olsun, bir sonraki sefer fonksiyona aktarılacak olan yeni akümülatör haline gelecektir. FP stilini döngüye alırken değerleri bu şekilde "hatırlarsınız". 2 sayı alan ve ekleyen bir fonksiyon verdim.
Bu ilk akümülatör; Akümülatörün listedeki herhangi bir öğe işlenmeden önceki gibi başlar. Sayıları toplarken, birlikte sayı eklemeden önceki toplam nedir? 0, ikinci argüman olarak geçtim.
Son olarak, haritada olduğu gibi, işlenmesi için sayı listesini de iletiyoruz.
Kıvrımlar hala mantıklı değilse, bunu düşünün. Yazarken:
# Notice I passed the plus operator directly this time,
# instead of wrapping it in another function.
fold(+, 0, numbers)
Temel olarak, geçirilen işlevi listedeki her öğe arasına koyarsınız ve ilk akümülatörü sola veya sağa eklersiniz (sol veya sağ kat olmasına bağlı olarak), bu nedenle:
[1, 2, 3, 4, 5]
Oluyor:
0 + 1 + 2 + 3 + 4 + 5
^ Note the initial accumulator being added onto the left (for a left fold).
Bu 15'e eşit.
map
Bir listeyi aynı uzunlukta başka bir listeye dönüştürmek istediğinizde a kullanın .
fold
Bir listeyi, sayı listesinin toplanması gibi tek bir değere dönüştürmek istediğinizde a kullanın .
@Jorg'un yorumlarda belirttiği gibi, "tek değer" bir sayı gibi basit bir şey olmak zorunda değildir; bir liste veya bir demet de dahil olmak üzere herhangi bir nesne olabilir! Benim için kıvrımları tıklatmamın yolu, kıvrım açısından bir harita tanımlamaktı . Akümülatörün nasıl bir liste olduğuna dikkat edin:
function map(f, list):
fold(
function(xs, x): # xs is the list that has been processed so far
xs.add( f(x) ) # Add returns the list instead of mutating it
, [] # Before any of the list has been processed, we have an empty list
, list)
Dürüst olmak gerekirse, her birini anladıktan sonra, neredeyse tüm döngülerin bir kat veya harita ile değiştirilebileceğini fark edeceksiniz.