Wordladder Journal Ep. 3

Oct 03, 2025
type GameState = { ... }
data GameEffect = Effect1 | Effect2 | ...

updateGame :: GameState -> Tuple GameState (Array GameEffect)

handleEffect :: GameState -> GameEffect -> Aff (Tuple GameState (Array GameEffect))
handleEffects :: GameState -> Array GameEffect -> Aff GameState
handleEffects = -- some fold function that reduces Array GameEffect into a GameState with side-effects run correctly

gameLoop :: GameState -> Aff Unit
gameLoop gameState = do
	let (Tuple newState effects) = updateGame gameState
	finalState <- handleEffects newState effects
	gameLoop finalState
handleEffects :: GameState -> Array GameEffect -> Aff GameState
handleEffects state effects = go effects state
  where
  go :: Array GameEffect -> GameState -> Aff GameState
  go effs s = case A.head effs of
    Nothing -> pure $ s
    Just e -> do
      Tuple s' newEffs <- handleEffect s e
      go (newEffs <> (fromMaybe [] $ A.tail effs)) s'
data GameEffect
  = Log String
  | Exit Int
  | AskUserToChooseDifficulty -- <- this one
  -- | others
handleEffect :: GameState -> GameEffect -> Aff (Tuple GameState (Array GameEffect))
handleEffect state AskUserToChooseDifficulty = do
  input <- readLine $ colorInfo "Choose word length (3, 4, or 5)"
  if (elem input [ "3", "4", "5" ]) then
    pure $ Tuple (state { currentState = DifficultySet (fromMaybe 3 (fromString input)) }) []
  else do
    log $ colorError "Invalid input. Please enter 3, 4, or 5."
    pure $ Tuple state [ AskUserToChooseDifficulty ]
updateGameState :: GameState -> Tuple GameState (Array GameEffect)

Update: