0

私はhttp://www.haskell.org/haskellwiki/State_Monad#Complete_and_Concrete_Example_1で与えられた例を試していました

これがどのようにソリューションを構成可能にするかは、私の理解を超えています。これが私が試したものですが、次のようにコンパイルエラーが発生します:

Couldn't match expected type `GameValue -> StateT GameState Data.Functor.Identity.Identity b0'
            with actual type `State GameState GameValue'
In the second argument of `(>>=)', namely `g2'
In the expression: g1 >>= g2
In an equation for `g3': g3 = g1 >>= g2
Failed, modules loaded: none.

コードは次のとおりです。終了行を参照してください

module StateGame where
import Control.Monad.State

type GameValue = Int
type GameState = (Bool, Int)

-- suppose I want to play one game after the other
g1 = playGame "abcaaacbbcabbab"
g2 = playGame "abcaaacbbcabb"
g3 = g1 >>= g2

m2 = print $ evalState g3 startState

playGame :: String -> State GameState GameValue
playGame []     = do
    (_, score) <- get
    return score

playGame (x:xs) = do
    (on, score) <- get
    case x of
         'a' | on -> put (on, score + 1)
         'b' | on -> put (on, score - 1)
         'c'      -> put (not on, score)
         _        -> put (on, score)
    playGame xs

startState = (False, 0)

main str = print $ evalState (playGame str) startState
4

2 に答える 2

2

2 つのゲームを組み合わせる方法は 2 つあります。最初のオプションは、最初のゲームの後に 2 番目のゲームを実行し、新しい状態から開始することです。これを行うには、次を使用します。

main = do
    print $ evalState g1 startState
    print $ evalState g2 startState

または、最初のゲームが終了した場所から 2 番目のゲームを開始することもできます。これを行うには、次を使用します。

g3 = do
    g1
    g2

...これは、次の構文糖衣です。

g3 = g1 >> g2

...そしてそれを実行します:

main = print $ evalState g3 startState
于 2012-09-20T15:51:02.573 に答える
2
g1 = playGame "abcaaacbbcabbab"
g2 = playGame "abcaaacbbcabb"
g3 = g1 >>= g2

g1g2はどちらもタイプState GameState GameValueです。しかし(>>=)、タイプがあります

(>>=) :: Monad m => m a -> (a -> m b) -> m b

したがって、その 2 番目の引数は関数でなければなりません。最初の引数が の場合g1、関数の型は

GameValue -> State GameState b

これは、エラー メッセージからの「期待される型」です。しかしg2、別のタイプがあります。それが「実際のタイプ」です。

の定義で必要なコンビネータg3(>>) :: Monad m => m a -> m b -> m b

g3 = g1 >> g2
于 2012-09-20T15:47:03.823 に答える