vavr to mniej więcej kopiuj wklej ze standadrowej biblioteki Scali (podstawowe monady Try/Either/Option + kolekcje niemutowalne + tuple i funkcje), więc jeśli nauczysz się używać jednego to drugie też szybko załapiesz.
Większy problem to jest to że ani jedno ani drugie nie dostarcza sposobu do pisania kodu czysto funkcyjnego (czyli monady IO
) oraz ładnego sposobu do pisania kodu asynchronicznego (czyli monady Task
).
IHMO w miarę prawdziwe programowanie funkcyjne zaczyna się od bibliotek Scalaz, Cats, ARROW, ZIO lub Functiona Java
Taka naprawdę super czysta czystość to brak jakichkolwiek efektów ubocznych, czyli brak obserwowalnego efektu działania programu (oprócz zużycia zasobów) ;]
Monady IO w przeciwieństwie do niemutowalnych struktur danych nie mają jasnych zalet (przynajmniej dla mnie). Przy monadach IO efekty uboczne i tak masz i masz mniej więcej te same problemy co w kodzie nieopakowującym efekty uboczne w abstrakcje. Możesz nawet napisać automat, który kod imperatywny zamieni na kod monadyczny 1:1 (tzn za pomocą monad IO możesz emulować mutowalność struktur danych, zmiennych lokalnych, stosu, itp itd). Ja tam nie jestem specjalnie przekonany do opakowywania wszystkiego w monady IO.
Jak dla mnie Scala jest takim trochę złotym środkiem - z jednej strony udostępnia masę niemutowalnych struktur danych z dobrą wydajnością (dzięki structural sharing w kolekcjach) oraz sporo mechanizmów umożliwiających funkcyjne abstrakcje (typy wyższych rzędów, rekurencja ogonowa, implicity, etc), a z drugiej nie zmusza mnie do pakowania się w monady IO na każdym kroku.
Ponadto nie ma jedynej słusznej monady IO. zio to nowe podejście do monad IO, które zmniejsza użycie monad transformers. Monada IO w zio to taka super-monada, łącząca wiele aspektów - izolacja efektów ubocznych, wartości opcjonalne, asynchroniczność, obsługa błędów, planowanie i zarządzanie zadaniami, itd Kiedyś to było rozczłonkowane na wiele monad łączonych tymi monad transformers co było uciążliwe.