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¶
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"
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"
Last update:
February 14, 2023
Created: August 18, 2022
Created: August 18, 2022