誰かがこのHaskellの関数を介して、私を歩くことができる(状態は関連モナド)?

StackOverflow https://stackoverflow.com/questions/1795785

  •  22-09-2019
  •  | 
  •  

質問

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>>=returngetをインライン化することにより、さらにお使いの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)は、計算の結果に影響を与えないながら、

は、それが状態モナド内に保持された状態を変更します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top