Monada pauzy
Monady potrafią robić wiele niesamowitych, szalonych rzeczy. Mogą tworzyć zmienne zawierające superpozycję wartości. Mogą one umożliwić dostęp do danych z przyszłości przed ich obliczeniem. Mogą pozwolić ci na pisanie destrukcyjnych aktualizacji, ale nie do końca. A potem monada kontynuacji pozwala na tozłamać ludzkie umysły! Ususally twoje własne. ;-)
Ale oto wyzwanie: czy potrafisz stworzyć monadę, która może byćwstrzymany?
data Pause s x instance Monad (Pause s) mutate :: (s -> s) -> Pause s () yield :: Pause s () step :: s -> Pause s () -> (s, Maybe (Pause s ()))
ThePause
monada jest rodzajem monady państwowej (stądmutate
, z oczywistą semantyką). Zwykle monada ma taką funkcję „uruchamiania”, która uruchamia obliczenia i przekazuje ci stan końcowy. AlePause
jest inny: zapewniastep
funkcja, która uruchamia obliczenia, dopóki nie wywoła magicznegoyield
funkcjonować. W tym przypadku obliczenia są wstrzymywane, powracając do wywołującego wystarczająco dużo informacji, aby wznowić obliczenia później.
Dla dodatkowej czujności: Pozwól dzwoniącemu zmodyfikować stan międzystep
połączenia. (Powyższe podpisy typów powinny umożliwiać to, na przykład.)
Przypadek użycia: Często łatwo jest napisać kod, który robi coś skomplikowanego, ale całkowity PITA, aby go przekształcićwydajność stany pośrednie w jego działaniu. Jeśli chcesz, aby użytkownik mógłzmiana coś w połowie realizacji, rzeczy bardzo szybko się komplikują.
Pomysły wdrożeniowe:
Oczywiście można to zrobić za pomocą wątków, zamków iIO
. Ale czy możemy zrobić lepiej? ;-)
Coś szalonego z monadą kontynuacji?
Może jakiś pisarz monad, gdzieyield
po prostu rejestruje aktualny stan, a następnie możemy „udawać”step
iterując przez stany w dzienniku. (Oczywiście wyklucza to zmianę stanu między krokami, ponieważ tak naprawdę nie „wstrzymujemy” niczego).