Wordladder Journal Ep. 4

Oct 05, 2025
data Free f a = Pure a | Free (f (Free f a))
updateGameState :: GameState -> Writer (Array GameEffect) GameState
updateGameState state = case state.currentState of
  NotInitialized -> do
    tell [ AskUserToChooseDifficulty ]
    pure state

  DifficultySet int -> do
    tell [ InitializeGame ]
    pure (state { dictionary = dict, wordLength = int })
    where
    dict = getAllWordsByLen int

  -- and more
loop state = do
        let Tuple newState effects = runWriter (updateGameState state)
        finalState <- handleEffects newState effects
        loop finalState
    loop initialState

-- where runWriter is:
runWriter :: Writer w a -> Tuple a w
-- where
-- w is Array GameEffect
-- a is GameState

Update

handleEffects :: GameState -> Array GameEffect -> Aff GameState
handleEffects initialState initialEffects =
  tailRecM go (Tuple initialState initialEffects)
  where
  go :: (Tuple GameState (Array GameEffect)) -> Aff (Step (Tuple GameState (Array GameEffect)) GameState)
  go (Tuple state effects) = case A.uncons effects of
    Nothing -> pure $ Done state
    Just { head: eff, tail: rest } -> do
      Tuple state' newEffects <- handleEffect state eff
      pure $ Loop (Tuple state' (newEffects <> rest))

data Step a b = Done b | Loop a