znalazłem następujący kod (w this blog post że rozwiązuje Coin Changer Kata):Proszę wyjaśnić mi następujący kod Clojure
(defn change-for [amount]
(let [denominations [25 10 5 1]
amounts (reductions #(rem %1 %2) amount denominations)
coins (map #(int (/ %1 %2)) amounts denominations)]
(mapcat #(take %1 (repeat %2)) coins denominations)))
Część znajdę trudno jest: (reductions #(rem %1 %2) amount denominations)
.
Jak się dowiedziałem, reductions właśnie oblicza wynikową kolekcję przyrostowo w oparciu o jakąś daną funkcję. Przykład: (reductions + [1 2 3])
podaje [1 3 6]
.
1 ; first element
1 + 2 ; second element
1 + 2 + 3 ; third element
Kolejna funkcja rem który oblicza pozostała część jest nadal bardzo prosty do zrozumienia.
Aby zrozumieć resztę kodu próbowałem następujące:
; first try, to see if this call works
; outside the original code (the change-for function)
(reductions #(rem %1 %2) 17 [10 5 1]) ; --> [17 7 2 0]
; tried to use the reductions which takes only one argument
; notice that 17 is now inside the array
(reductions #(rem %1 %2) [17 10 5 1]) ; --> [17 7 2 0]
; further simplified the expression
(reductions rem [17 10 5 1]) ; --> [17 7 2 0]
Ostatnim krokiem było usunięcie funkcji anonimowy, jak to opisano w this blog post.
W tym momencie sytuacja staje się zagmatwana (przynajmniej dla mnie): rem
przyjmuje 2 argumenty i nie rozumiem, jak są stosowane podczas korzystania z tablicy [17 10 5 1]
. Próbowałem następujące połączenia:
(rem [17 10 5 1]) ; --> gives error
(rem [17 10 5 1] [17 10 5 1]) ; --> also gives error
(rem 17 10) ; --> works, but how do you use it with collections?
Może ktoś mi wyjaśnić, jak to rem
funkcja działa z funkcją reductions
?
Inną rzeczą, ja nie bardzo rozumiem to: jak są te argumenty procentowe stosowane (w #(rem %1 %2)
)? Mam na myśli skąd pochodzą? Próbowałem wywoływać rem
w następujący sposób, ale pojawia się błąd: (#(rem %1 %2) 17 [10 5 1])
. Musi być coś, co funkcja reductions
wykonuje za kulisami, aby to działało, prawda?
Początkowo myślałem, że #(rem %1 %2)
był zestawem. Te deklarowane są w podobny sposób jak zestawy i może być łatwo nadużywana (przez kogoś dopiero zaczynasz z Clojure):
(type #{1 2 3}) ; --> clojure.lang.PersistentHashSet
(type #(1 2 3)) ; --> user$eval12687$fn__12688
Czy ktoś może wskazać mi na miejscu/książki/cokolwiek to wyjaśnia sztuczek Clojure takich jak "Specjalny formularz do anonimowej funkcji"? Większość zasobów daje najprostsze konstrukcje (te, które są podobne do wszystkich innych pochodnych lispów) bez wchodzenia w zawiłości Clojure. Znalazłem a site, który wygląda całkiem nieźle (a także wyjaśnia anonimowe funkcje, o których wspomniałem powyżej). Jakieś inne takie zasoby?