OK, więc łatwo byłoby przetasować własną funkcję z zastosowaniem wewnątrz lub użyć dedykowanej wersji odwrotnej, która działa lepiej (ale tylko) na łańcuchach. Głównymi rzeczami, o których warto tutaj pomyśleć, jest arność (ilość i typ parametrów) funkcji str, oraz fakt, że odwrotność działa na kolekcję.
Oznacza to, że reverse działa nie tylko na ciągi, ale także na wszystkie inne kolekcje. Jednak z powodu odwrotnego oczekuje zbiór jako parametr, traktuje ciąg jako zbiór znaków
(reverse "Hello")
i zwraca jedną jak również
(\o \l \l \e \H)
Teraz, jeśli po prostu zastąpić funkcje gromadzenia, ty można dostrzec różnicę:
(str '(\o \l \l \e \H))
"(\\o \\l \\l \\e \\H)"
podczas
(str \o \l \l \e \H)
"olleH"
Duża różnica między nimi to ilość parametrów. W pierwszym przykładzie str przyjmuje jeden parametr, zbiór 5 znaków. W drugim kroku str przyjmuje 5 parametrów: 5 znaków.
Czego oczekuje funkcja str?
(doc str)
-------------------------
clojure.core/str
([] [x] [x & ys])
With no args, returns the empty string. With one arg x, returns
x.toString(). (str nil) returns the empty string. With more than
one arg, returns the concatenation of the str values of the args.
Tak więc, gdy podasz jeden parametr (zbiór), wszystkie powroty str jest toString kolekcji. Ale aby uzyskać pożądany wynik, musisz podać 5 znaków jako oddzielne parametry do str, zamiast samej kolekcji. Zastosuj to funkcja, która służy do "dostania się" do kolekcji i sprawi, że to się stanie.
(apply str '(\o \l \l \e \H))
"olleH"
Funkcje obsługi wielu oddzielnych parametrów są często postrzegane w Clojure, więc dobrze jest uświadomić sobie, kiedy i dlaczego trzeba użyć zastosowania. Inną stroną do zdawania sobie sprawy jest to, dlaczego pisarz funkcji str sprawił, że akceptuje wiele parametrów zamiast kolekcji?Zwykle istnieje całkiem niezły powód. Jaki jest powszechny przypadek użycia funkcji str? Niepodzielenie na pewno zbioru oddzielnych znaków, ale łączenie wartości, łańcuchów i wyników funkcji.
(let [a 1 b 2]
(str a "+" b "=" (+ a b)))
"1+2=3"
Co gdybyśmy mieli str, który zaakceptowałby pojedynczą kolekcję jako parametr?
(defn str2
[seq]
(apply str seq)
)
(str2 (reverse "Hello"))
"olleH"
Fajnie, działa! Ale teraz:
(let [a 1 b 2]
(str2 '(a "+" b "=" (+ a b)))
)
"a+b=(+ a b)"
Hmmm, jak to rozwiązać? :)
W tym przypadku, aby str akceptował wiele parametrów, które są oceniane przed uruchomieniem funkcji str, daje najłatwiejszą składnię. Ilekroć musisz użyć str na kolekcji, aplikacja to prosty sposób na konwersję kolekcji na osobne parametry.
Stworzenie łańcucha, który akceptuje kolekcję i sprawdzenie, czy każda jego część wymaga więcej wysiłku, pomaga tylko w rzadziej używanych przypadkach, powoduje bardziej skomplikowany kod lub składnię lub ogranicza możliwość zastosowania. Więc może istnieć lepszy sposób odwracania łańcuchów, ale odwrotne, zastosowanie i str są najlepsze w tym, co robią.
Ach ma sens, dzięki. Nadal jestem zbyt mocno zakorzeniony w uniwersum Haskella, w którym łańcuchy są po prostu połączonymi listami. – djhworld