5

Próbuję zrozumieć kontynuację ogólnie po tym tutorial.Jak działa `get` w wersji CPS monady State?

Jednak mam trudności zrozumieć poniższy przykład w rozdziale 2.10:

# let get() = 
    shift (fun k -> fun state -> k state state) ;; 
get : unit => ’a = <fun> 

state jest typu int przypuszczam. To, czego nie otrzymuję, to typ k. Według mojego rozeznania, k przechwytuje wszystkie obliczenia pochodzi następnie po get(), a ponieważ mówimy o monady państwowej k jest rozsądna do reprezentowania obliczenia, które będą kontynuowane przez przyjęcie int, stąd

k : int => 'a 

ale z kod, to nie wydaje się, aby to zrobić, a to trwa state po raz drugi, co rzeczywiście implikuje:

k : int => int => 'a 

ale nie rozumiem, gdzie drugi pochodzi iw którym wyczuć get jest z wpisz unit => 'a zamiast unit => int => 'a?

porównaniu do faktycznej realizacji monada stan, zamieszanie dodaje więcej:

newtype StateT s m a = StateT { runStateT :: s -> m (a,s) } 

tj przejściowy stan jest reprezentowany jako funkcję od stanu do krotki wyniku i stanu, który odpowiada mój pierwszy zrozumienie.

Czy ktoś może dać ołów?

Po drugie, jak mam zaimplementować get tutaj przy użyciu Haskella Control.Monad.Trans.Cont? Mam problemy z pocieszające system typu.


UPDATE

Wydaje Dostałem drugi:

Prelude Control.Monad.Trans.Cont> let get() = shift $ \k -> return $ \i -> k i i 

Ale ja nadal nie rozumiem, dlaczego muszę zastosować stan dwukrotnie do kontynuacji.

+0

@Bergi to tak naprawdę nazywane OchaCaml. Postępuję zgodnie z samouczkiem, ale nie sądzę, aby używane języki wpływały na zrozumienie tego pojęcia w tym przypadku. – HuStmpHrrr

Odpowiedz

3

zastosować k na state dwukrotnie, ponieważ pierwszy z nich odpowiada wynikowi get() (chcemy get jest efektem będzie zdobycie aktualny stan i odsyłając je jako wynik), a drugi odpowiada przejściu stanu po get (który, ponieważ get nie zmienia stanu, jest taki sam jak stan przed get) do następnego obliczenia stanowego.

Innymi słowy, ponieważ monada stan jest State s a ~ s -> (a, s), jego wersja CPS jest State s r a ~ s -> (a -> s -> r) -> r, a więc dla get : State s s, ponieważ a ~ s, kontynuacja będzie funkcją typu s -> s -> r.

+0

to główna część, której nie otrzymuję. czy dalsza kontynuacja wystarczy, tylko przekazując obecny stan?Nie rozumiem też, jak przejść z wersji monad stanu do wersji cps. – HuStmpHrrr

+0

także w jaki sposób mogę poznać rodzaj kontynuacji po prostu patrząc na kod? która część powinna wyglądać, otwór czy nie dziura? – HuStmpHrrr

+0

Pomyśl o tym, co chciałbyś przekazać, jeśli wynikiem 'get' byłby bieżący stan + 1 (ustalenie go dla' State Int' dla przykładu). Kolejny stan będzie nadal taki sam jak stan przychodzący, ale wynik będzie inny. Więc musisz przekazać 'state + 1' jako argument wynikowy i' state' jako nowy argument state do kontynuacji. – Cactus