2

問題は、タイプの動作を作成する方法がわからないことですBehavior t GameState

私はもっ​​と多くのコードを持っていますが、問題について話すために必要だと思うものを表示しようとしています. 記入すべき空白があるかどうか教えてください。私が持っているものは次のとおりです。

data GameState = GameState {agent    :: Agent
                           ,universe :: Universe
                           }

type Universe = Gr Planet ()

data Command = Move PlanetName
             | Look
             | Quit
                 deriving Show

data PlayerCommand = PlayerCommand Command PID
                   | Null
                       deriving Show

updateGS :: PlayerCommand -> GameState -> GameState
updateGS (PlayerCommand (Move planet) pid) gs =
   let agent = getAgent pid gs
       nodes = labNodes $ universe gs
       current = location agent
       Just fromP = lookup (fromEnum current) nodes
       Just toP   = lookup (fromEnum planet) nodes
       fromNode = fromEnum current
       toNode = fromEnum planet
       uPlayer = Player pid (getPlanetName toP) (Location planet)
       mData = MoveData uPlayer (toNode,toP) (fromNode,fromP) nodes
       uPlanets = updateLNodeList mData
   in GameState uPlayer (mkGraph uPlanets $ labUEdges gates

initialGS :: GameState
initialGS = GameState initPlayer (makeUniverse makePlanetNodes)

そしてイベントネットワーク

makeNetworkDescription :: AddHandler PlayerCommand -> IO EventNetwork
makeNetworkDescription addCommandEvent = compile $ do
   eInput <- fromAddHandler addCommandEvent
   let bCommand = stepper Null eInput
   eCommandChanged <- changes bCommand
   let bGameState :: Behavior t GameState
       bGameState = stepper initialGS 
   reactimate $ (\n -> appendFile "output.txt" ("Command is " ++ show n)) <$> eCommandChanged

bGameState は eCommandChange を使用する必要があると思いますが、型に問題があります

stepper :: a -> Event t a -> Behavior t a

これにより、に変換eInput :: Event t PlayerCommandする 必要があると信じるようになります。eGameState :: Event t GameStatestepperBehavior t GameState

それで、私の質問は、私の考え方は正しいですか? そうでない場合は、リダイレクトできますか? もしそうなら、どのようにeGameState :: Event t GameState見えますか?

以下、回答者様へのお返事です。最初に考えたときaccumB、作成中に型エラーが発生しました。私があなたの提案を試したときに何が起こったのですか。

let bGameState :: Behavior t GameState
    bGameState = accumB initialGS $ updateGS <$ eInput

エラーが発生します

 Couldn't match expected type `GameState'
             with actual type `PlayerCommand'
 Expected type: GameState -> GameState
   Actual type: PlayerCommand -> GameState -> GameState
 In the first argument of `(<$)', namely `updateGS'
 In the second argument of `($)', namely `updateGS <$ eInput'

それについて何をすべきかわからない。あなたの例を見て、答えが明確になるかどうかを確認します。accumB私が集中していたので、指摘してくれてありがとうstepper

提案されたコードを研究すればするほど、型エラーに戸惑います。

4

1 に答える 1

2

実際、a を記憶し、それに関数をGameState適用して新しいイベントを作成するイベントを作成する必要があります。それが関数とその従兄弟updateGSの目的です。特に、あなたは書くことができますaccumEaccumB

bGameState = accumB initialGS $ updateGS <$> eInput

このパターンの詳細については、サンプル ページの例、特に Counter.hs および TwoCounters.hs の例を参照してください。


言及する価値のあるもう 1 つのポイントはchanges、低レベルのフレームワークを扱っている場合を除き、関数を避けることをお勧めすることです。ドキュメントに記載されているように、いくつかの制限があります。reactimate最も厄介な制限は、実行されるまで値を使用できないことです。そうすれば無限ループを簡単に作ることができます。その目的は本当に非常に狭いです。

あなたの場合、 はbCommandとにかく余計に思えますeCommandChanged = eInput

士気: 出来事を行動に変えるのは簡単ですが、後戻りはできません。

于 2012-10-24T13:54:05.730 に答える