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?