I'm trying to understand the Reader monad, and I'm following this answer https://stackoverflow.com/a/14179721/10116440 which has this example:
import Control.Monad.Reader
data GameState = NotOver | FirstPlayerWin | SecondPlayerWin | Tie
data Game position
= Game {
getNext :: position -> [position],
getState :: position -> GameState
}
getNext' :: position -> Reader (Game position) [position]
getNext' position
= do game <- ask
return $ getNext game position
getState' :: position -> Reader (Game position) GameState
getState' position
= do game <- ask
return $ getState game position
negamax :: Double -> position -> Reader (Game position) Double
negamax color position
= do state <- getState' position
case state of
FirstPlayerWin -> return color
SecondPlayerWin -> return $ negate color
Tie -> return 0
NotOver -> do possible <- getNext' position
values <- mapM ((liftM negate) . negamax (negate color)) possible
return $ maximum values
The first thing I don't understand is return $ getNext game position
. getNext
, when applied to a game
, returns position -> [position]
. This, when applied to position
, returns [position]
. So the line return $ getNext game position
should returng something other than Reader (Game position) [position]
, I don't know which this something is, because I don't know how the return
is defined for the Reader
monad.
Anyways, which "instance" of the Game
will ask
return? I don't understand, there's none in this code. Also, runReader
is never called, so what are the Reader
results of getNext
, getState
and negamax
used for?
Could someone complete this example with how would runReader
actually be run in this code, and which game
instance is returned by ask
?
Also, why Reader env a
and not simply Reader a
?