Evaluator
- Throw an error of type
ChessError
. This is what requires theMonadError ChessError
constraint. gets display
is the same asfmap display get
: it accesses the state (of typeBoard
), which requires theMonadState Board
constraint, and appliesdisplay
to it, to return aText
value.get
is the local state. It takes no arguments.- Recall that a
Board
value represents the board as a function from aFile
andRank
to a square state, so this function is what we need to change, when updating theBoard
. put
takes 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:
January 18, 2023
Created: August 18, 2022
Created: August 18, 2022