2017-05-18 6 views
0

これは、状態のモナドよりもブロックの使用法に関する質問です。次のコードでは、doブロックをrunStateで直接使用できますが、flipを使用して引数の順序を逆にして、使用する初期状態が最初に指定されるようにするだけです。runStateとdoブロック

なぜ、flip構造体を使用する必要があるのですか。つまり、doブロックをrunStateの最初の引数として配置する方法はありますか?

module Main where 

import qualified Data.Map as Map 
import Control.Monad.State 

type MapS = Map.Map Int String 

-- Add an item (key value pair) to map 
addItemToMap :: Int -> String -> State MapS() 
addItemToMap x s = modify $ Map.insert x s 

main :: IO() 
main = do 
    let r = flip runState Map.empty $ do 
     addItemToMap 101 "one hundred and one" 
     addItemToMap 1001 "one thousand and one" 
    print r 
+0

'flip' *は*引数の順序をどのように切り替えるかです。 –

+0

しかし、私の質問は、この文脈で通常の順序で引数を指定してrunStateを呼び出すのではなく、何をフリップするかについてではありません。私はこのようにdoを呼び出す方法を知らない。 – andro

答えて

3

doブロックをrunStateの最初の引数にする方法はありますか?

あなたが他の式で行うようにあなたは、括弧でdoブロックを囲むことができます。

let r = runState (do 
     addItemToMap 101 "one hundred and one" 
     addItemToMap 1001 "one thousand and one") Map.empty 

flipがしばしばでrunStateで使用されている理由である、しかし、少しぎこちないですあなたが描く方法。

1

runStateの引数の順序は、おそらく開始状態(第2引数)がより頻繁にアクション(最初の引数)よりも変化するであろうという仮定に基づいて選択しました。引数の順序を反転する場合は、flip(またはその他の同等のメソッド)を使用する以外には何もありません。それはまさにフリップのためのものです。

ご希望の場合は、flip runStateに簡単に再利用できる名前を付けることができます。たとえば、flip execStateの(対応する)lens has &~です。

関連する問題