Uczę się javascript FP, czytając książkę DrBoolean .
Szukałem biblioteki programowania funkcjonalnego. Znalazłem Ramdę i Folktale. Obie twierdzą, że są funkcjonalną biblioteką programowania.
Ale są tak różni:
Ramda wydaje się zawierać funkcje użytkowe do obsługi list: mapowania, redukcji, filtrowania i czyste funkcje: curry, compose. Nie zawiera nic do czynienia z monadą, funktorem.
Folktale nie zawiera jednak żadnego narzędzia do listy lub funkcji. Wydaje się, że implementuje niektóre struktury algebraiczne w javascript, takie jak monada: Może, zadanie ...
Właściwie znalazłem więcej bibliotek, wszystkie wydają się należeć do dwóch kategorii. Podkreślenie i lodash są jak Ramda. Fantasy-land, pointfree-fantasy są jak legenda.
Czy te bardzo różne biblioteki można nazwać funkcjonalnymi , a jeśli tak, to co sprawia, że każda z nich jest biblioteką funkcjonalną?
źródło
[1,2,3].map(fnSquare).reduce(fnSum)
2. w dużej mierze akademickie struktury typu „look ma no var ” w układzie Y-kombinator. 3. używanieFunction.prototype
do modyfikowania zachowania innych funkcji, takich jakvar isMissingID=fnContains.partial("id").negate();
Odpowiedzi:
Funkcje funkcjonalne
Nie ma wyraźnej granicy tego, co definiuje programowanie funkcjonalne lub bibliotekę funkcjonalną. Niektóre funkcje języków funkcjonalnych są wbudowane w Javascript:
Inne są możliwe do wykonania w JavaScript z pewną ostrożnością:
Jeszcze inne są częścią ES6 i są teraz częściowo lub w pełni dostępne:
Jest też wiele innych, które są naprawdę poza normalnym zasięgiem Javascript:
Biblioteka może więc wybierać, jakie rodzaje funkcji próbuje obsługiwać i nadal rozsądnie nazywać ją „funkcjonalną”.
Specyfikacja krainy fantasy
Fantasy-land to specyfikacja wielu standardowych typów przeniesionych z matematycznej teorii kategorii i algebry abstrakcyjnej do programowania funkcjonalnego, takich jak Monoid , Functor i Monad . Te typy są dość abstrakcyjne i rozszerzają prawdopodobnie bardziej znane pojęcia. Na przykład funktory to kontenery, które można
map
przerzucić za pomocą funkcji, tak jak tablica może byćmap
przerzucona za pomocą funkcjiArray.prototype.map
.Folktale
Folktale to zbiór typów implementujących różne części specyfikacji Fantasy-land oraz niewielki zbiór towarzyszących funkcji użytkowych. Typy te są rzeczy podoba Może , albo , zadanie (bardzo podobny do tego, co gdzie indziej nazywa się przyszłości, a bardziej legalny kuzyn obietnicę), a Validation
Folktale jest prawdopodobnie najbardziej znaną implementacją specyfikacji Fantasy-land i cieszy się dużym uznaniem. Ale nie ma czegoś takiego jak ostateczna lub domyślna implementacja; Fantasy-land określa tylko typy abstrakcyjne, a implementacja musi oczywiście tworzyć takie konkretne typy. Twierdzenie Folktale o byciu biblioteką funkcjonalną jest jasne: dostarcza typów danych spotykanych zwykle w funkcjonalnych językach programowania, które znacznie ułatwiają programowanie w sposób funkcjonalny.
Ten przykład z dokumentacji Folktale ( uwaga : nie w ostatnich wersjach dokumentacji) pokazuje, jak można go użyć:
// We load the library by "require"-ing it var Maybe = require('data.maybe') // Returns Maybe.Just(x) if some `x` passes the predicate test // Otherwise returns Maybe.Nothing() function find(predicate, xs) { return xs.reduce(function(result, x) { return result.orElse(function() { return predicate(x)? Maybe.Just(x) : /* otherwise */ Maybe.Nothing() }) }, Maybe.Nothing()) } var numbers = [1, 2, 3, 4, 5] var anyGreaterThan2 = find(function(a) { return a > 2 }, numbers) // => Maybe.Just(3) var anyGreaterThan8 = find(function(a) { return a > 8 }, numbers) // => Maybe.Nothing
Ramda
Ramda (zastrzeżenie: jestem jednym z autorów) to zupełnie inny rodzaj biblioteki. Nie zapewnia nowych typów. 1 Zamiast tego zapewnia funkcje ułatwiające obsługę istniejących typów. Opiera się na pojęciach łączenia mniejszych funkcji w większe, pracy z niezmiennymi danymi, unikania skutków ubocznych.
Ramda działa szczególnie na listach, ale także na obiektach, a czasami na łańcuchach. Przekazuje również wiele swoich wywołań w taki sposób, że będzie współpracować z Folktale lub innymi implementacjami Fantasy-land. Na przykład
map
funkcja Ramdy działa podobnie do funkcji naArray.prototype
, więcR.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]
. Ale ponieważ FolktaleMaybe
implementuje specyfikację Fantasy-landFunctor
, która określa również mapę, możesz również użyćmap
z nią Ramdy :R.map(square, Maybe.Just(5)); //=> Maybe.Just(25); R.map(square, Maybe.Nothing); //=> Maybe.Nothing
Ramda twierdzi, że jest biblioteką funkcjonalną, ponieważ ułatwia tworzenie funkcji, nigdy nie mutuje danych i przedstawia tylko czyste funkcje. Typowym zastosowaniem Ramdy byłoby zbudowanie bardziej złożonej funkcji poprzez komponowanie mniejszych, jak widać w artykule o filozofii Ramdy
// :: [Comment] -> [Number] var userRatingForComments = R.pipe( R.pluck('username') // [Comment] -> [String] R.map(R.propOf(users)), // [String] -> [User] R.pluck('rating'), // [User] -> [Number] );
Inne biblioteki
To nie jest do końca dokładne. Przede wszystkim Fantasy-land to po prostu specyfikacja, którą biblioteki mogą zdecydować się zaimplementować dla różnych typów. Folktale to jedna z wielu implementacji tej specyfikacji, chyba najlepiej dopracowana, na pewno jedna z najbardziej dojrzałych. Pointfree-fantasy i ramda-fantasy to inne, a jest ich znacznie więcej .
Podkreślenie i lodash są z pozoru podobne do Ramdy, ponieważ są bibliotekami typu `` grab-bag '', dostarczającymi wielu funkcji o znacznie mniejszej spójności niż coś takiego jak Folktale. A nawet specyficzna funkcjonalność często pokrywa się z Ramdą. Ale na głębszym poziomie Ramda ma zupełnie inne obawy niż te biblioteki. Najbliższymi kuzynami Ramdy są prawdopodobnie biblioteki takie jak FKit , Fnuc i Wu.js .
Bilby to osobna kategoria, która zapewnia zarówno szereg narzędzi, takich jak te dostarczone przez Ramdę, jak i niektóre typy zgodne z Fantasy-land. (Autor Bilby jest również oryginalnym autorem Fantasy-landu.)
Twoja decyzja
Wszystkie te biblioteki mają prawo nazywać się funkcjonalnymi, chociaż różnią się znacznie podejściem funkcjonalnym i stopniem zaangażowania funkcjonalnego.
Niektóre z tych bibliotek dobrze ze sobą współpracują. Ramda powinna dobrze współpracować z Folktale lub innymi implementacjami Fantasy-land. Ponieważ ich obawy ledwie się pokrywają, tak naprawdę nie są ze sobą sprzeczne, ale Ramda robi wszystko, co w ich mocy, aby zapewnić stosunkowo płynną współpracę. Jest to prawdopodobnie mniej prawdziwe w przypadku niektórych innych kombinacji, które możesz wybrać, ale prostsza składnia funkcji ES6 może również zmniejszyć ból związany z integracją.
Wybór biblioteki, a nawet stylu biblioteki będzie zależał od projektu i preferencji. Dostępnych jest wiele dobrych opcji, a ich liczba rośnie, a wiele z nich znacznie się poprawia. To dobry czas na programowanie funkcjonalne w JS.
1 Cóż, istnieje poboczny projekt, ramda-fantasy, który robi coś podobnego do tego, co robi Folktale, ale nie jest częścią podstawowej biblioteki.
źródło
yield
Ułatwia wykonywanie tego rodzaju leniwego przetwarzania list za pomocąLazy
lublz.js
. Ale to nie pomaga w lenistwie na poziomie językowym.someFunc(a + b)
w JS najpierw dodaje wartości,a
ab
następnie dostarcza wynik jako parametr do someFunc. Odpowiednik w Haskell tego nie robi. Jeśli wywołana funkcja nigdy nie używa tej wartości, nigdy nie wykonuje dodawania. Jeśli w końcu go użyje, uważa się, że wyrażenie jest obliczane, dopóki jego wynik nie będzie potrzebny. Jeśli nigdy nie zrobisz niczego, co wymusi to (jak IO), to nigdy nie wykona obliczeń.