Frage

tick :: State Int Int
tick = get >>= \n ->
       put (n+1) >>= \y ->
       return n

Ich bin verwirrt, wie put (n+1) hat keine Auswirkungen auf das Endergebnis dieser Funktion überhaupt. Es scheint, wie diese Funktion sollte der Ausgangszustand unverändert zurück. Ich versuche, durch das in meinem Kopf zu laufen, aber ich immer laufen Platz heraus halten Dinge im Ort. : \

Wenn jemand mich durch die Auswertung dieser Funktion gehen könnte, wäre es sehr hilfreich sein.

War es hilfreich?

Lösung

  

... Wie wird die Aktualisierung setzt den Zustand, in erster Linie? Es scheint nur zu nichts sitzen tun ...

Ah, jetzt verstehe ich Ihre Frage. Sie fragen sich, wie put (und get) Arbeit, nicht wahr?

Vielleicht ein Beispiel in JavaScript helfen (die Sprache mit dem tatsächlichen wandelbarem Zustand):

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

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

Ich hoffe, das das veranschaulicht, während n nicht ändert, wird der innere Zustand wird noch aktualisiert. Wenn Sie tick() zweimal ausführen, wird der Staat zweimal erhöht werden.

Um zu Haskell zurück, hier ist die vollständige Definition (die relevanten Teile) des 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)

Versuchen Sie nun tick Beispiel noch weiter ausbauen, indem Sie manuell inlining >>=, return, get und put. Hoffentlich wird es mehr klar machen, wie Staat funktioniert.

Andere Tipps

Sie sind ganz richtig. Das „Ergebnis“ der tick „Funktion“ ist der Anfangswert des Staates.

Jetzt ist natürlich tick nicht die wirkliche „Funktion“, sondern eine Berechnung, die lesen und schreiben können Zustand bevor ein Ergebnis.
In diesem Fall wird der Zustand aktualisiert, aber Sie sind immer noch den ursprünglichen Wert des Staates zurückkehren:

-- 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 diesem Fall, da Sie nie den Zustand wieder innerhalb tick Inspektion, du bist nicht den geänderten Zustand zu sehen. Wenn jedoch eine andere Berechnung nach tick geschieht, kann es den aktualisierten Zustand sehen.

Zum Beispiel tut tick zweimal (der zweite wird den aktualisierten Zustand lesen):

-- 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

es könnte helfen, es zu schreiben, mit do Notation

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

, während die put (n+1) nicht das Ergebnis der Berechnung auswirken, hat es den Zustand ändern, die innerhalb des Staates Monade gehalten wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top