On Thu, 2008-09-04 at 18:41 +0100, Andrew Coppin wrote: > Ryan Ingram wrote: > > It's pretty simple, I think. > > > > type ExpGen = ReaderT [String] Gen > > > > arbExp :: ExpGen Expression > > -- exercise for the reader > > > > instance Arbitrary Expression where > > arbitrary = runReaderT arbExp [] > > coarbitrary = coarbExp > > > > coarbExp (Var s) = variant 0 . coarbitrary s > > coarbExp (Apply a b) = variant 1 . coarbitrary a . coarbitrary b > > coarbExp (Lambda s e) = variant 2 . coarbitrary s . coarbitrary e > > > > instance Arbitrary Char where > > arbitrary = elements "abcdefghijklmnopqrstuvwxyz_" > > coarbitrary = coarbitrary . fromEnum > > > > o_O > > I love the way other people have wildly different ideas of "simple" than > me. I'm staring at this and completely failing to comprehend it. (But > then, anything with "co" in the name generally makes little sense to > me...) Why on earth would you need a reader monad? Surely if you want to > add bound variables and then later query what variables are bound, you'd > want a state monad? Hmm, I'm completely lost here.
Motto (off-the-cuff): State monads are for APIs with function names like `set'; reader monads are for APIs with function names like `with'. In this case, you definitely do not want to bring names into scope with bringNameIntoScope :: Name -> ExpGen () because then you'd just have to implement bringNameOutofScope :: Name -> ExpGen () and remember to call it after you've generated the body of the lambda, except that you have to check before bringing the name into scope whether it's already in scope and if so make sure it's still in scope afterwards. A simpler alternative is to pull out the entire scope, using get, save it off, modify the state, and then put it back later: withNameInScope :: Name -> ExpGen alpha -> ExpGen alpha withNameInScope name a = do scope <- get modify (name:) x <- a set scope return x But by adopting that API, you're suggesting the use of a reader monad to implement scoping, since withNameInScope would then be just withNameInScope name = local (name:) jcc http://haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-Reader-Class.html#v%3Alocal _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe