2012-10-23 2 views
2

문제를 함께 두는 것은 내가 더 많은 코드를 입력 Behavior t GameState기능 바나나 여행자 - 행동 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 

유형은 내가 사용할 수있는 eGameState :: Event t GameState으로 eInput :: Event t PlayerCommand을 변환 할 필요가 생각하는 stepper을 작성하여 Behavior 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' 

그것에 대해 무엇을 할 확실하지 않음 산출한다. 저는 여러분의 모범을보고 대답이 명확 해지는 지 살펴 보겠습니다. 밖으로 향한 주셔서 감사합니다 stepperstepper

더 많이 나는 제안 된 코드를 공부할수록 더 많은 종류의 오류에 당황 스럽다.

답변

2

사실, GameState을 기억하고 updateGS 함수를 적용하여 새 이벤트를 만드는 이벤트를 만들어야합니다. 그것이 함수 accumE과 그 사촌 accumB의 목적입니다. 특히, 당신은

bGameState = accumB initialGS $ updateGS <$> eInput 

가이 패턴에 대한 자세한 내용은 쓰기 examples pages, 특히 Counter.hs 및 TwoCounters.hs 예에 예를 살펴 수 있습니다.


언급 할 가치가 다른 점은 당신이 낮은 수준의 프레임 워크 물건을 다루는 경우를 제외하고 changes 기능을하지 않도록하는 것이 좋습니다 것입니다. 문서에서 언급했듯이 몇 가지 제한이 있습니다. 가장 엄격한 제한은 reactimate이 실행될 때까지 값을 사용할 수 없다는 것입니다. 그런 식으로 무한 루프를 쉽게 만들 수 있습니다. 그 목적은 실제로 매우 좁습니다.

귀하의 경우 bCommand은 불필요하게 보이며, eCommandChanged = eInput입니다.

사기 : 이벤트를 행동으로 변환하는 것은 쉽지만 돌아갈 길이 없습니다.

+0

나는 (<$)' to '(<$>)을 변경했지만 승인을 받아야합니다. –

+0

감사합니다. 편집에 대한 메시지를받지 못했지만 방금 직접 변경했습니다. –