誰かがこのHaskellの関数を介して、私を歩くことができる(状態は関連モナド)?
質問
tick :: State Int Int
tick = get >>= \n ->
put (n+1) >>= \y ->
return n
私はput (n+1)
がすべてで、この関数の最終結果に影響を持っているかのよう困惑しています。この機能は変わらず、初期状態に戻す必要がありますように思えます。私は私の心の中でこの介して実行しようとしているが、私は場所で物事を保持するために部屋を出て走り続けます。 :\
誰かがこの関数の評価を通じて、私を歩くことができれば、それは本当に参考になる。
解決
...どのようプットが最初の場所での状態を更新していますか?それはちょうど何もしないそこに座っているように見える...
ああ、今私はあなたの質問を理解しています。あなたが迷っているかput
(およびget
)仕事、右?
たぶん、JavaScriptでの例では、(実際の可変状態で言語)に役立ちます。
var s; // mutable state
function get() { return s; }
function put(x) { s = x; }
function tick() {
var n = get();
put(n + 1);
return n;
}
はn
は変わりませんが、私は、これがそれを示して願って、内部状態はまだ更新されます。あなたが二回tick()
を実行すると、状態が2回インクリメントされることになります。
はここState
モナドのの完全な定義(関連部分が)だ、ハスケルに戻って取得するには
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)
さて、手動tick
、>>=
、return
とget
をインライン化することにより、さらにお使いのput
の一例を拡大してみてください。うまくいけば、それは国家がどのように機能するかをより明確になります。
他のヒント
あなたは完全に正しいです。 tick
「機能」の「結果」は状態の初期値である。
さて、もちろん、tick
は本当の「機能」ではありませんが、結果を生成する前に、の状態のを読み書きできる計算。
この場合、の状態が更新されますが、あなたはまだ状態の元の値を返しています:
-- 4 is the inital state
ghci> runState tick 4
(4, 5)
-- 4 is the result of the tick computation, 5 is the updated state
この場合、あなたはtick
内で再び状態を検査することはありませんしているので、あなたが変更された状態を見ていません。他のいくつかの計算がtick
後に発生した場合は、それが更新された状態を見ることができます。
たとえば、(1秒が更新された状態を読み込みます)を2回tick
をやってます:
-- 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
それ使用して、それを書くために役立つかもしれないdo
表記
tick :: State Int Int
tick = do
n <- get -- get the state
put (n+1) -- save an incremented state
return n -- return the original state
put (n+1)
は、計算の結果に影響を与えないながら、は、それが状態モナド内に保持された状態を変更します。