Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7983265
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T10:54:47+00:00 2026-06-04T10:54:47+00:00

I have been following and expanding on the tutorial Write Yourself A Scheme .

  • 0

I have been following and expanding on the tutorial Write Yourself A Scheme. I have a type LispVal wrapped up in a couple of layers of monad transformers:

import qualified Data.Map as M

data LispVal   = ...
data LispError = ...

type Bindings = M.Map String (IORef LispVal)
data Env = Environment { parent :: Env, bindings :: IORef Bindings }

type IOThrowsError = ErrorT LispError IO
type EvalM = ReaderT Env IOThrowsError

The idea with using ReaderT is that I’ll be able to automatically pass the environment (which maintains variable bindings) around through the evaluator, and it will be obvious where it is used because there will be a call to ask. This seems preferable to explicitly passing the environment around as an extra parameter. When I come to implement continuations I’ll want to do a similar trick with the ContT monad transformer, and avoid passing around an extra argument for the continuation.

However, I haven’t figured out how it’s possible to modify the environment by doing this. For example, to define a new variable or to set the value of an old one.

For a concrete example, let’s say that whenever I evaluate an if statement, I want to bind the variable it to the result of the test clause. My first thought was to modify the environment directly:

evalIf :: [LispVal] -> EvalM LispVal
evalIf [test, consequent, alternate] = do
  result <- eval test
  bind "it" result
  case (truthVal result) of
    True  -> eval consequent
    False -> eval alternate

Here truthVal is a function that assigns a Bool to any LispVal. But I can’t figure out how to write the function bind so that it modifies the environment.

My second thought was to use local:

evalIf :: [LispVal] -> EvalM LispVal
evalIf [test, consequent, alternate] = do
  result <- eval test
  local (bind "it" result) $ case (truthVal result) of
    True  -> eval consequent
    False -> eval alternate

But here bind needs to have type Env -> Env, and since I’m using IORefs as values in the environment, I can only write a function with the signature Env -> IO Env.

Is this even possible, or do I need to use StateT instead of ReaderT?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T10:54:48+00:00Added an answer on June 4, 2026 at 10:54 am

    ReaderT is used when you have scoped, read-only environments. E.g. in interpreters.
    Environments in ReaderT nest lexically, so you can augment the environment each time you encounter a binding. Like so:

    eval (LetE x e1 e2) = do
        env <- ask
        v   <- eval e1
        local (M.insert x v) (eval e2)
    

    Here’s an old post of mine with some examples.

    If you have such an environment, it shouldn’t be necessary to also use IORefs, unless you’re playing funny games with dynamic scoping? What is the reason for the IORefs?

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have been following a tutorial on how to write a basic tile map
I have been following a couple of articles regarding RESTful web services with WCF
I have been following the affableBean tutorial from the NetBeans site located here .
I have been following the tutorial on Microsofts website and they use GameTime to
I have been following a short tutorial to build a tab menu on my
I'm new to NHibernate... I have been following this NHibernate Tutorial from Gabriel Schenker
Have been following Rails Tutorial by Michael Hart rails version 3.0 on mac OS
I have been following this tutorial series for OpenGL : GLUT : http://www.lighthouse3d.com/opengl/glut/ I
I have been following a tutorial on creating an iPhone app with multiple xibs.
I have been following a tutorial on the internet it can be found at

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.