Search code examples
haskellmonadsmonad-transformersreader-monad

What does "ask" mean in Haskell and what's the difference of it and "asks" function?


I can't understand how to use the ask function, I know how to use the asks function, but I don't know if they're related.

I was reading the "What I wish I knew when learning Haskell" of Stephen and I found this example:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State

type Stack = [Int]
type Output = [Int]
type Program = [Instr]

type VM a = ReaderT Program (WriterT Output (State Stack)) a

newtype Comp a = Comp { unComp :: VM a }
    deriving (Functor, Applicative, Monad, 
                MonadReader Program, MonadWriter Output, 
                  MonadState Stack)

data Instr = Push Int
            | Pop
            | Puts

evalInstr :: Instr -> Comp ()
evalInstr instr = case instr of
                    Pop -> modify tail
                    Push n -> modify (n:)
                    Puts -> do
                        tos <- gets head
                        tell [tos]

eval :: Comp ()
eval = do
    instr <- ask
    case instr of
      [] -> return ()
      (i:is) -> evalInstr i >> local (const is) eval

execVM :: Program -> Output
execVM = flip evalState [] . execWriterT . runReaderT (unComp eval)

program :: Program
program = [
        Push 42,
        Push 27,
        Puts,
        Pop,
        Puts,
        Pop
    ]

main :: IO ()
main = mapM_ print $ execVM program

So, my question is: from where the list was taken?


Solution

  • ask is asks id. While in...

    do
        x <- asks f
        -- etc.
    

    ... x will be the result of applying f to the environment of your MonadReader computation, in...

    do
        x <- ask
        -- etc.
    

    ... x will be the environment itself.