Naprawdę mam problemy ze zrozumieniem callCC. Dostaję moc kontynuacji i wykorzystałem tę koncepcję w niektórych moich projektach, aby stworzyć fajne koncepcje. Ale nigdy nie musiałem używać czegoś o większych możliwościach niż cont :: ((a->r)->r)-> Cont r a
.
Po użyciu ma sens, dlaczego nazywają Cont Monad matką wszystkich monad, JESZCZE, nie rozumiem, kiedy powinienem użyć callCC
, i to jest dokładnie moje pytanie.
haskell
functional-programming
monads
Alejandro Navas
źródło
źródło
Cont
? Kiedy mówisz, że nie musiałeś używać czegoś mocniejszego niżcont
, czy to oznacza, że nie używałeśreset
czyshift
też?reset
lubshift
. Użyłem go do zdefiniowania osadzonego języka, który można zawiesić, dopóki dana akcja nie zostanie rozwiązana przez inny proces, a następnie zostanie wznowiona z podaną „kontynuacją”. Może mam wrażenie, że mam duże doświadczenie z Cont Monad, ale nie bardzo, naprawdę chcę po prostu zrozumieć callCCOdpowiedzi:
callCC
daje semantykę „wczesnego powrotu”, ale w kontekście monadycznym.Powiedz, że chciałeś
doOne
, a jeśli to powróciTrue
, natychmiast przerwiesz, w przeciwnym razie przejdziesz dodoTwo
idoThree
:Widzisz
if
tam rozgałęzienie? Jedna gałąź nie jest taka zła, można sobie z nią poradzić, ale wyobraź sobie, że istnieje wiele takich punktów, w których po prostu chcesz zwolnić za kaucją? To staje się bardzo brzydkie bardzo szybko.Dzięki
callCC
możesz mieć „wczesny powrót”: płacisz za kaucją w punkcie rozgałęzienia i nie musisz zagnieżdżać reszty obliczeń:O wiele przyjemniej czytać!
Co ważniejsze, ponieważ
ret
tutaj nie ma specjalnej składni (jakreturn
w językach podobnych do C), ale tylko wartość jak każda inna, możesz przekazać ją również do innych funkcji! Funkcje te mogą następnie wykonać tak zwany „powrót nielokalny” - tzn. Mogą „zatrzymać”doThings
obliczenia, nawet z wielu zagnieżdżonych wywołań głęboko. Na przykład, mogędoOne
oddzielić sprawdzanie wyniku do oddzielnej funkcji,checkOne
takiej jak ta:źródło
b
jest w zasadzie tylko symbolem wieloznacznym, dzięki czemu możesz połączyć więcej kontynuacji w callCC. W każdym razie poret
zastosowaniu kontynuacja wywołana przez wywołanie cc „zwróci” wszystko, co zostało wprowadzoneret
. To dość skomplikowane, ale całkiem sprytne, a jednocześnie niezwykle potężne. Nie widzę wielu miejsc, w których użycie takiej mocy nie jest jak zabicie muchy za pomocą broni nuklearnej