2009-11-25 9 views
7
tick :: State Int Int 
tick = get >>= \n -> 
     put (n+1) >>= \y -> 
     return n 

Sono confuso su come put (n+1) abbia alcun effetto sul risultato finale di questa funzione. Sembra che questa funzione dovrebbe restituire lo stato iniziale invariato. Sto provando a ripercorrere questo nella mia mente, ma continuo a correre fuori dalla stanza per tenere le cose a posto. : \Qualcuno può guidarmi attraverso questa funzione di Haskell (relativa alla monade di stato)?

Se qualcuno mi poteva camminare attraverso la valutazione di questa funzione, sarebbe davvero utile.

risposta

10

... Come si aggiorna lo stato in primo luogo? Sembra stia seduto lì senza far nulla ...

Ah, ora capisco la tua domanda. Ti stai chiedendo come funziona il put (e get), giusto?

Forse un esempio in JavaScript aiuterà (una lingua con stato mutevole reale):

var s; // mutable state 
function get() { return s; } 
function put(x) { s = x; } 

function tick() { 
    var n = get(); 
    put(n + 1); 
    return n; 
} 

Spero che questo dimostra che, mentre n non cambia, lo stato interno ancora viene aggiornata. Se si esegue tick() due volte, lo stato verrà incrementato due volte.

di tornare a Haskell, ecco la definizione completa di (parti rilevanti) del State Monade:

newtype State s a = State { runState :: s -> (a, s) } 

instance Monad (State s) where 
    return a = State $ \s -> (a, s) 
    m >>= k = State $ \s -> let 
     (a, r) = runState m s 
     in runState (k a) r 

get = State $ \s -> (s, s) 
put s = State $ \_ -> ((), s) 

Ora provate a espandere la vostra tick esempio ulteriormente inlining manualmente >>=, return, get e put. Speriamo che diventi più chiaro come funziona lo Stato.

+0

Ti ho battuto per 5 secondi interi! È strano come tendo a capire le cose da solo/dopo/ho fatto la domanda. Apprezzo le risposte! :) – Rayne

7

Hai perfettamente ragione. Il "risultato" della "funzione" tick è il valore iniziale dello stato.

Ovviamente, tick non è la vera "funzione", ma un calcolo che può leggere e scrivere stato prima di produrre un risultato.
In questo caso, lo stato di è aggiornato, ma si sta ancora restituendo il valore originale dello stato:

-- 4 is the inital state 
ghci> runState tick 4 
(4, 5) 
-- 4 is the result of the tick computation, 5 is the updated state 

In questo caso, dal momento che non si è mai ispezionare di nuovo lo stato interno tick, è Non vedo lo stato cambiato. Tuttavia, se qualche altro calcolo avviene dopo tick, può vedere lo stato aggiornato.

Per esempio, facendo tick due volte (la seconda leggerà lo stato aggiornato):

-- 4 is the inital state 
ghci> runState (tick >> tick) 4 
(5, 6) 
-- 5 is the result of the tick computation executed twice, 
-- 6 is the updated state 
+0

Quello che non capisco è come sta succedendo. Come si aggiorna lo stato, ma il valore di ritorno rimane lo stesso?In che modo si pone l'aggiornamento dello stato in primo luogo? Sembra che stia seduto lì senza fare niente. – Rayne

+0

Infatti, lo stato viene aggiornato, ma il valore di ritorno, 'n' rimane lo stesso. Vedi la mia altra risposta http://stackoverflow.com/questions/1795785/can-somebody-walk-me-through-this-haskell-function-state-monad-related/1796544#1796544 –

5

potrebbe aiutare a scrivere utilizzando do notazione

tick :: State Int Int 
tick = do 
    n <- get -- get the state 
    put (n+1) -- save an incremented state 
    return n -- return the original state 

mentre il put (n+1) non lo fa impatto il risultato del calcolo, altera lo stato che si tiene all'interno della monade di stato.

+0

Ciò non aiuta veramente. Ho risolto il mio esempio per cercare di capirlo. Sto cercando di capire cosa sta succedendo qui sotto per fare in modo che questo cambiamento di stato avvenga. – Rayne

+0

abbastanza giusto, avrei postato le definizioni di get e put, ma immagino che sia stato fatto. – barkmadley

+0

Questo non avrebbe aiutato neanche. : p Avevo già guardato quelle definizioni il più profondamente possibile, è stato quel dettaglio cruciale che mi sfugge agli occhi. Non è colpa tua, è colpa mia se non riesci a formulare correttamente una domanda. – Rayne

Problemi correlati