Evaluator
- Throw an error of type
ChessError. This is what requires theMonadError ChessErrorconstraint. gets displayis the same asfmap display get: it accesses the state (of typeBoard), which requires theMonadState Boardconstraint, and appliesdisplayto it, to return aTextvalue.getis the local state. It takes no arguments.- Recall that a
Boardvalue represents the board as a function from aFileandRankto a square state, so this function is what we need to change, when updating theBoard. puttakes an argument and sets the state to that argument.
Analysis¶
MonadError and MonadState are typeclasses for types with the ability to throw errors and mutate local state respectively. See the monad transformer library (mtl) for more.
With that in mind, read the type signature of evaluate as follows: evaluate is a function that takes an Instruction and returns Text, but with the possibility of throwing an error of type ChessError, and of changing the state (of type Board).
We can think of evaluate as taking a synactic description of an Instruction and evaluating it into a result. For example ReplInstruction "quit" is a description of an instruction, but throwError Exit is the actually "program" that will quit the repl.
evaluate¶
```haskell
evaluate :: (MonadError ChessError m, MonadState Board m) => Instruction -> m Text evaluate instr = case instr of ReplInstruction "quit" -> throwError Exit ReplInstruction "display" -> gets display Set file rank piece -> do (Board boardFunc) <- get let newBoard = Board ( \f r -> if f == file && r == rank then HasPiece piece else boardFunc f r ) put newBoard return $ display newBoard ReplInstruction _ -> throwError $ ReplError "no such instruction" ```
evaluate' :: (MonadError ChessError m, MonadState Board m) =>
Instruction -> m Text
evaluate' = \case
ReplInstruction "quit" -> throwError Exit
ReplInstruction "display" -> gets display
Set file rank piece -> do
(Board boardFunc) <- get
let newBoard =
Board
( \f r ->
if f == file && r == rank
then HasPiece piece
else boardFunc f r
)
put newBoard
return $ display newBoard
ReplInstruction _ -> throwError $ ReplError "no such instruction"
```haskell
evaluate :: (MonadError ChessError m, MonadState Board m) => Instruction -> m Text evaluate instr = case instr of ReplInstruction "quit" -> throwError Exit ReplInstruction "display" -> gets display Set file rank piece -> do let updateBoard (Board boardFunc) = Board ( \f r -> if f == file && r == rank then HasPiece piece else boardFunc f r) modify updateBoard gets display ReplInstruction _ -> throwError $ ReplError "no such instruction" ```
Created: August 18, 2022