typ FMapy w funktora jest:
fmap :: Functor f => (a -> b) -> f a -> f b
wygląda na to, po pierwsze zastosowania funkcji (A -> B) parametru FA stworzyć efekt typu B, a następnie zastosować f nią , a wynikiem jest fb
To jest typ fmap
, ale twoja interpretacja tego, co oznacza ten typ, jest błędna.
Wydaje się, że zakładasz, że f a
ma jeden parametr i że ten parametr ma typ a
.
Rozważmy xs :: [a]
:
- Może
xs = []
.
- Być może
xs = [x1]
.
- Być może
xs = [x1, x2]
.
- ...
Typ f a
to funktor f
z jednego parametru typu a
. Jednak wartości o wartości typu f a
niekoniecznie przyjmują postać F x
, jak widać z pierwszego i trzeciego przypadku powyżej.
Rozważmy teraz fmap f xs
:
- Może
fmap f xs = []
.
- Być może
fmap f xs = [f x1]
.
- Być może
fmap f xs = [f x1, f x2]
.
- ...
Nie koniecznie zastosować f
na wszystkich (pierwszym przypadku)! Lub możemy zastosować go więcej niż jeden raz (trzeci przypadek).
Co możemy zrobić, to wymienić rzeczy typu a
na rzeczy typu b
. Ale pozostawiamy większą strukturę w stanie nienaruszonym - nie dodaje się nowych elementów, nie usuwa się żadnych elementów, ich kolejność pozostaje niezmieniona.
Teraz pomyślmy o funktorze (c ->)
. (Pamiętaj, że funktor przyjmuje tylko jeden parametr, więc wejście do (->)
jest poprawione.)
Czy c -> a
zawiera nawet a
? Może w ogóle nie zawierać żadnych a
s, ale może jakoś magicznie wydobyć go z powietrza, gdy damy mu c
. Ale wynik z fmap
ma typ c -> b
: musimy tylko dostarczyć b
z tego, gdy jesteśmy przedstawieni z c
.
Możemy więc powiedzieć, fmap f x = \y -> f (x y)
.
W tym przypadku stosujemy f
na żądanie - za każdym razem, gdy funkcja, którą zwracamy, zostanie zastosowana, zostanie również zastosowana f
.
tak, twoja odpowiedź jest świetna! Popełniłem wielki błąd. Dziękuję Ci bardzo. –
Mylę "parametr typu" z konkretnym parametrem –