Możesz myśleć o tym, że docierasz do tego samego miejsca dwoma różnymi trasami. Z jednej strony zaczynasz od monady czytelnika, która jest po prostu rodzajem opakowania dla funkcji. Wtedy zdajesz sobie sprawę, że chcesz zintegrować tę funkcję czytnika w większą monadę z innymi "efektami", więc utworzysz transformator monadowy ReaderT
. W tym momencie sensowne jest zaimplementowanie oryginalnego Reader[E, ?]
jako ReaderT[Id, E, ?]
.
Z drugiej strony, chcesz, aby typ reprezentował strzałki Kleisli (tj. Funkcje z monadycznym typem powrotu). Okazuje się, że jest to to samo co ReaderT
, więc po prostu stwórz ten alias.
Nie ma nic strasznie tajemniczego w części "okazuje się". To trochę tak, jakby zacząć od klasy typu Addable
dla rzeczy liczbowych, a następnie zdecydować, aby uczynić ją bardziej ogólną i ostatecznie zakończyć się klasą typów, która zapewnia tylko asocjacyjną operację "dodawania". Odtworzyłeś na nowo Semigroup
! Nadal możesz chcieć zachować nazwę z powodów historycznych lub pedagogicznych lub po prostu dla wygody.
To wszystko, co się dzieje z Reader
i ReaderT
-Ty nie potrzebę te aliasy, ale mogą być wygodne, i może przyczynić się do poprawy czytelności kodu.
Czytnik i ReaderT/Kleisli nie są izomorficzne (jak powiedziałeś, pierwszym jest specjalizacja drugiego). – ZhekaKozlov
@ZhekaKozlov Dzięki. Myliłem się (nie zaktualizuję pytania). – Michael