W wolnym czasie uczę się Haskella, więc jest to pytanie początkujące.Zrozumienie, jak Jest to instancja Functor'a
W moich odczytów natknąłem przykład ilustrujący jak Either a
jest wystąpienie Functor
:
instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
Teraz staram się zrozumieć, dlaczego mapy wdrożeniowe w przypadku konstruktora Right
wartości, ale nie w przypadku Left
?
Oto moje rozumienie:
pierwsze chciałbym przepisać powyższy przypadek jako
instance Functor (Either a) where
fmap g (Right x) = Right (g x)
fmap g (Left x) = Left x
now:
wiem, że
fmap :: (c -> d) -> f c -> f d
jeśli podstawimy
f
zEither a
otrzymujemyfmap :: (c -> d) -> Either a c -> Either a d
rodzaj
Right (g x)
jestEither a (g x)
i rodzajg x
jestd
, tak mamy, że rodzajRight (g x)
jestEither a d
, czyli czego oczekujemy odfmap
(patrz punkt 2 powyżej)teraz, jeśli spojrzymy na
Left (g x)
możemy zastosować to samo rozumowanie, aby powiedzieć, że jego typ jestEither (g x) b
, czyliEither d b
, co nie jest, czego oczekujemy odfmap
(patrz punkt 2 powyżej): thed
powinien być drugi parametr nie pierwszy! Więc nie możemy mapować ponadLeft
.
Czy moje rozumowanie jest prawidłowe?
albo być może więcej niż oczywiście Bifunctor funktora - Bifunctor ma bimap operacji - bimap :: (a -> M) -> (b -> n) -> fab -> fm n. Daje to odwzorowanie na lewą i prawą sprawę. Standardowa biblioteka Haskella nie ma klasy Bifunctor, ponieważ jest tam o wiele mniej Bifunktorów niż Funktorów "na wolności", chociaż jest przydatna zarówno dla Either, jak i pair (a, b). –
W 3 używasz (g x) jako części typu, ale jest to wartość. Wygląda na to, że napisałeś 'typeof (g x)' tam, a nie '(g x)' sam. – Peaker
@stephen tetley: to interesujące! Dzięki – MarcoS