
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-C...