2015-03-01 15 views
7

Jestem obecnie czytania doskonała „Learn Użytkownikowi Haskell za wielkie dobro”, aw section about functors jest przykładem zaangażowania Either których nie rozumiem:Różnica pomiędzy lewą a prawą stroną

ghci> fmap (replicate 3) (Right "blah") 
Right ["blah","blah","blah"] 
ghci> fmap (replicate 3) (Left "foo") 
Left "foo" 

Dlaczego ten ostatni nie jest Left ["foo", "foo", "foo"]?

+3

Jeśli chcesz tego ostatniego zachowania , [Albo jest bifunctor] (https://hackage.haskell.org/package/bifunctors-4.2/docs/Data-Bifunctor.html). – kqr

Odpowiedz

12

Konstruktor Left na Either jest zaimplementowany jako "przypadek awarii". Podobnie jak inne funktory, gdy wartość tego błędu przejdzie do równania, uniemożliwia to jakiekolwiek rzeczywiste obliczenia. Tak więc, gdy zastosujesz fmap do Left "foo", natychmiast zwróci tę samą wartość "niepowodzenia".

Można to zobaczyć patrząc jak Either realizuje fmap:

instance Functor (Either a) where 
    fmap f (Right x) = Right (f x) 
    fmap f (Left x) = Left x 

Chodzi o to, że Left "foo" byłby rzeczywiście coś bardziej opisowy, jak Left "Value could not be computed". Jeśli spróbujesz zastosować dodatkowe funkcje do tej wartości, po prostu chcesz, aby "błąd" został poprawnie przekazany.

Jeśli to nie pomaga, tylko sobie wyobrazić, jak fmap będzie działać na innym rodzaju, gdzie w przypadku awarii jest bardziej oczywista, np

-- Maybe: failure value is `Nothing` 
fmap (replicate 3) (Nothing) 

To daje Nothing nie [Nothing, Nothing, Nothing]

+5

Dzięki za szybką odpowiedź! Zrozumiałem już zachowanie "Może". Co mi pomogło z "Albo" to przypomnieć sobie, że ani "ani" nie jest funktorem, ale "Albo"! – mkrieger1

+0

@ mkrieger1 Prosta zasada mnemoniczna, którą należy zapamiętać: "Prawy" przypadek oznacza poprawny/udany/"właściwy", "Lewy" oznacza "niedobry", a więc zły/niepoprawny/nie. – chi

+2

@chi .... i tym samym zostawiają go samodzielnie przez instancje Functor/Applicative/Monad. – AndrewC

Powiązane problemy