2014-04-17 11 views
6

Podpis funkcji w Haskell >> to:Dlaczego nic >> Tylko 3 nie ma nic w Haskell?

(>>) :: m a -> m b -> m b 

i wdrożenie domyślne to:

x >> y = x >>= \_ -> y 

Przez to, rozumiem, że funkcja >> zawsze zwraca jego właściwą parametru niezależnie od wartość lewej. Wartość lambda nie uwzględnia nawet wartości lewego parametru (x). Dlaczego więc Nothing >> Just 3 jest równe Nothing? Czy nie powinien po prostu zwracać Just 3, ponieważ jest to wartość argumentu po prawej?

wiem, że każda wartość Just powróci Nothing, gdy wiąże się z Nothing, ale w tym przypadku nie jest Nothing nawet rejestrowany przez lambda. czego mi brakuje?

Pytanie dodatkowe, >>= nazywa się bind. Co to jest nazwa >>?

Dzięki.

Odpowiedz

13

Ponieważ powiązanie nawet nie obchodzi, jaka jest wartość lambda!

Just x >>= f = f x 
Nothing >>= _ = Nothing 

Uwaga: (Nothing >>=) nie ocenia swojego drugiego argumentu.

+0

Ah, oczywiście ... Tego właśnie mi brakowało. Dzięki! – Buzu

6

Aby naprawdę zrozumieć, co (>>) robi w tym przypadku trzeba patrzeć na the definition of (>>=) for Maybe:

(Just x) >>= k  = k x 
Nothing >>= _  = Nothing 

Nothing >>= k ocenia się Nothing niezależnie od tego, co jest funkcja k. W konkretnym przypadku (>>), k po prostu jest \_ -> y.

+0

Wiedziałem, że czegoś mi brakuje. Dzięki: D – Buzu

2

Myślę, że są dwa sposoby na wyjaśnienie wyboru.

  1. odwołujesz się do faktu, że Może, w przeciwieństwie do IO na przykład, nie ma skutków ubocznych. W przeciwnym razie brak oceny drugiego argumentu nie miałby sensu. W tym ujęciu wydaje się, że jest to arbitralny wybór z logicznej perspektywy, choć z pewnością jest bardziej skuteczny, o ile nieoczekiwany.

  2. czynisz Nic nie stanowi błędu. Wtedy błąd w pierwszym argumencie uniemożliwiłby ocenę drugiego argumentu. Wydaje się, że jest to uzasadnienie wybrane przez autorów:

http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Data-Maybe.html#Maybe

-- The 'Maybe' type is also a monad. It is a simple kind of error 
-- monad, where all errors are represented by 'Nothing'. 
+0

To ma sens. Tak naprawdę nie spieram się z logiką, po prostu nie widziałem powodu, dla którego zwrócono Nic, ale jako @duplode i leftaroundabout wskazał, że ma to związek z tym, jak definiuje się funkcję bind dla Może. Dzięki! – Buzu

+1

Dziękuję za pytanie! Zaskoczył mnie również wynik. – seanmcl

+0

To sprawia, że ​​czuję się lepiej wiedzieć, że nie jestem jedynym, który tęsknił;) – Buzu

1

Istnieje kilka rzeczy, chciałbym dodać do innych dobrych odpowiedzi.

  1. Powodem Nothing >>= f musi być Nothing się tak dlatego, że to niemożliwe, by sprawdzić, czy rzeczywiście f używa argumentu (bez strasznych niebezpiecznych hacki, przynajmniej).

  2. x >> y = x >>= \_ -> y to nie tylko domyślna implementacja. Definicja >> powinna zawsze dawać taki sam wynik jak ten. Można go przeciążać tylko dlatego, że czasami może być wdrażany bardziej efektywnie.

+0

Dzięki za dodanie tej informacji. – Buzu

3

Przez to, rozumiem, że funkcja >> zawsze zwraca jego prawą parametru niezależnie od wartości lewa

Jest źródłem twojego zamieszania!

m >>= f wywołuje f do określenia wartości „znajduje się wewnątrz” m „łączenie” wyniki (w których co to znaczy wartości do „Znaleziono wewnątrz” w jednowartościowy wartość i co to znaczy „połączenie” jest monada-specyficzne) .

m >> n musi być równoważny z m >>= \_ -> n. Tak więc dla każdej wartości znajduje się wewnątrz m, to wywoła na nim \_ -> n. Ale Nothing w monadzie Maybe nie ma wartości "wewnątrz" tej wartości. Tak więc \_ -> n nie można nawet wywołać niczego, aby go zignorować i zwrócić n! Tak więc Nothing >>= \_ -> n musi zwrócić coś, co nie zależy od n, ponieważ nie ma możliwości wywoływania funkcji w celu uzyskania n. W tym kontekście nie ma również żadnych wartości owiniętych typów, więc jedyną dostępną opcją jest po prostu Nothing.

Więc zamiast intuicji, aby zrozumieć, że ignoruje lewą i zwraca to, co jest po prawej, lepiej jest myśleć, że zajmuje ona "monadyczną strukturę" tego, co jest po lewej i wiąże ją z monadyczną wartością na prawo. "Monadyczna struktura" jest ręcznym terminem określającym "wszystko, co definiuje monadyczną wartość inną niż wartości wewnątrz niej".

listA >> listB robi to samo niezależnie od konkretnych wartości w listA, ale ma znaczenie, ile elementów w nim jest. ioA >> ioB robi to samo, bez względu na to, jaka wartość jest wytwarzana przez wykonanie ioA, ale ma znaczenie, czy efekty uboczne zostały wykonane w celu jej wyprodukowania. stateA >> stateB ignoruje wartość produkowaną przez stateA, ale wysyła bieżący stan do stateB. I maybeA >> maybeB robi to samo niezależnie od konkretnej wartości wewnątrz maybeA, ale ma znaczenie, czy istnieje wartość, czy nie. Zwróć uwagę, że przypadek listy zachowuje się bardzo podobnie do Maybe; jeśli listA jest pusty, wtedy listA >> listB musi być pusty.

Co do twojego pytania o bonus, kiedy czytam sobie kod (w mojej głowie), wymawiam zarówno >>= jak i >> jako "bind"; kiedy jestem szukając przy kodzie, a także wymawiając go, jest wystarczająco niewerbalna świadomość kontekstu, że ta niejednoznaczność nie ma znaczenia.Właściwie nie wiem, co chciałbym powiedzieć na głos z kimś o >>= i >>; może "bindować" i "zapomnieć o bindach"?

+0

Dzięki za wyjaśnienie. Dodaje wiele wartości do poprzednich odpowiedzi. – Buzu