Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://www.haskell.org/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Using state inside quickcheck generators (Alexander MacDonald) 2. Re: Maybe, Either (Michael Snoyman) 3. Re: Maybe, Either (Alexander Dunlap) 4. Re: Maybe, Either (Brent Yorgey) 5. Re: Maybe, Either (Brandon S. Allbery KF8NH) 6. Re: Using state inside quickcheck generators (Kyle Murphy) ---------------------------------------------------------------------- Message: 1 Date: Tue, 15 Sep 2009 14:56:08 -0700 From: Alexander MacDonald <alex...@adobe.com> Subject: [Haskell-beginners] Using state inside quickcheck generators To: "beginners@haskell.org" <beginners@haskell.org> Message-ID: <c6d55b88.90b2%alex...@adobe.com> Content-Type: text/plain; charset="iso-8859-1" Hi guys, I¹ve been using quickcheck for a while and I¹m having no problem making generators for my data types, however recently I stumbled upon a situation where I need to maintain State inside the quickcheck generator functions. Here's a simple example, imagine I've got a basic language which only has two features, variable definitions and assignments: type Script = [Statement] data Name = Name String deriving (Show,Eq) data Statement = Def Name Int | Assign Name Name deriving Show Generating random scripts is easy enough, just make each type an instance of Arbitrary with a suitable generator function, however I want to make sure that the generated scripts are syntactically valid. In this case that means no "Name" can be used in an "Assign" statement unless it has previously been defined by a "Def" statement. My knowledge of using monads is somewhat basic so I'm struggling to figure out how to use the State monad with QuickCheck. I've pasted my current effort on the web: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=9412 If anyone could spare a moment to glance at my code and give me a push in the right direction that would be much appreciated! Thanks, Alex Mac ------------------------------ Message: 2 Date: Wed, 16 Sep 2009 01:19:53 +0300 From: Michael Snoyman <mich...@snoyman.com> Subject: Re: [Haskell-beginners] Maybe, Either To: "Brandon S. Allbery KF8NH" <allb...@ece.cmu.edu> Cc: beginners@haskell.org Message-ID: <29bf512f0909151519q5e3c3bhd3ce4063ff7f2...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" On Tue, Sep 15, 2009 at 11:49 PM, Brandon S. Allbery KF8NH < allb...@ece.cmu.edu> wrote: > On Sep 15, 2009, at 16:21 , Michael Snoyman wrote: > > On Tue, Sep 15, 2009 at 3:08 AM, Brent Yorgey <byor...@seas.upenn.edu>wrote: > >> It doesn't work in *all* monads -- it only works in monads which >> support a sensible notion of failure. This is exactly what is >> captured by the MonadPlus constraint on my version of mLookup. And, >> in fact, any monad in context of which you would want to use mLookup >> (IO, Maybe, [], ...) are already instances of MonadPlus. >> > > I'm looking at the Control.Monad documentation ( > http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html), > and it doesn't seem that IO is an instance of MonadPlus. I get the same > results with a simple code check. Can you clarify? Calling lookup from IO is > a common use case for me. > > > That's a bit of stupidity I wish would be fixed; for some bizarre reason, > the instance is in Control.Monad.Error. > And according to the documentation, that instance has a broken version of mzero. So it seems the argument of use MonadPlus because fail is not always defined properly doesn't exactly hold much water here. Can you tell me why you would still recommend representing lookup failure with the mzero function instead of the seemingly more aptly named and more available fail function? Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20090915/215e6da9/attachment-0001.html ------------------------------ Message: 3 Date: Tue, 15 Sep 2009 15:33:25 -0700 From: Alexander Dunlap <alexander.dun...@gmail.com> Subject: Re: [Haskell-beginners] Maybe, Either To: Michael Snoyman <mich...@snoyman.com> Cc: beginners@haskell.org Message-ID: <57526e770909151533y67f86275u5bd3c5222e9...@mail.gmail.com> Content-Type: text/plain; charset=UTF-8 On Tue, Sep 15, 2009 at 8:56 AM, Michael Snoyman <mich...@snoyman.com> wrote: > > > On Tue, Sep 15, 2009 at 6:21 AM, Brandon S. Allbery KF8NH > <allb...@ece.cmu.edu> wrote: >> >> On Sep 14, 2009, at 14:42 , Michael Snoyman wrote: >> >> I understand that fail being in Monad is controversial, but my version of >> the function works in *all* monads. This is very >> >> Not really; "fail" in non-MonadPlus-es is a rather poorly defined notion, >> and there are no guarantees that the result will be at all sane. Â "mzero" is >> well defined. > > mzero also does not allow giving error messages. There are times when you > want to be able to fail with an explanation of why. fail seems to fit the > bill properly for this (fail taking a String argument and all...). In general, I think this is a bad idea. Except for short, throwaway code, Strings should not be used to encode errors simply because if your error message is a String, client code basically has no choice but to show it to the user and probably exit: since it's quite hard for the code to parse the String back in to find out what the error message was, it's hard for client code to recover from the error. If you have multiple types of errors from a single function, it's better to define your own error type with constructors representing different types of errors so client code can figure out what went wrong. (And in many cases, I have found that if a function can fail in multiple ways, I am trying to do too much in one function. There are, of course, numerous exceptions.) Alex ------------------------------ Message: 4 Date: Tue, 15 Sep 2009 18:50:45 -0400 From: Brent Yorgey <byor...@seas.upenn.edu> Subject: Re: [Haskell-beginners] Maybe, Either To: beginners@haskell.org Message-ID: <20090915225045.ga30...@seas.upenn.edu> Content-Type: text/plain; charset=us-ascii On Wed, Sep 16, 2009 at 01:19:53AM +0300, Michael Snoyman wrote: > On Tue, Sep 15, 2009 at 11:49 PM, Brandon S. Allbery KF8NH < > allb...@ece.cmu.edu> wrote: > > > I'm looking at the Control.Monad documentation ( > > http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html), > > and it doesn't seem that IO is an instance of MonadPlus. I get the same > > results with a simple code check. Can you clarify? Calling lookup from IO is > > a common use case for me. > > > > > > That's a bit of stupidity I wish would be fixed; for some bizarre reason, > > the instance is in Control.Monad.Error. > > > > And according to the documentation, that instance has a broken version of > mzero. So it seems the argument of use MonadPlus because fail is not always > defined properly doesn't exactly hold much water here. Can you tell me why > you would still recommend representing lookup failure with the mzero > function instead of the seemingly more aptly named and more available fail > function? The IO instance of mzero is only broken in the sense that it does not satisfy the law m >> mzero === mzero since the effects of m will happen on the left but not on the right. But this is to be expected with the IO monad: if you have to perform some I/O effects in order to find out whether the computation fails or not, you can't expect to roll back the effects once you do fail. In practice I don't think this would be much of an issue. But anyway, the reason I recommend not using fail is because it is an inelegant, unprincipled hack. If you have no problem with inelegant, unprincipled hacks then I guess I won't be able to convince you. =) Also, if you haven't already, you should read the email from Conor McBride in this same thread: after reading his email I'm now of the opinion that you shouldn't even use MonadPlus, but simply use Maybe. -Brent ------------------------------ Message: 5 Date: Tue, 15 Sep 2009 23:09:16 -0400 From: "Brandon S. Allbery KF8NH" <allb...@ece.cmu.edu> Subject: Re: [Haskell-beginners] Maybe, Either To: Michael Snoyman <mich...@snoyman.com> Cc: beginners@haskell.org Message-ID: <b5485229-a015-4e74-9d9e-0e360b3f3...@ece.cmu.edu> Content-Type: text/plain; charset="us-ascii" Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/beginners/attachments/20090915/a43cfbdc/PGP-0001.bin ------------------------------ Message: 6 Date: Thu, 17 Sep 2009 01:40:31 -0400 From: Kyle Murphy <orc...@gmail.com> Subject: Re: [Haskell-beginners] Using state inside quickcheck generators To: Alexander MacDonald <alex...@adobe.com> Cc: "beginners@haskell.org" <beginners@haskell.org> Message-ID: <2db78cee0909162240o33a9eeb6vdba21a12947b4...@mail.gmail.com> Content-Type: text/plain; charset="iso-8859-1" I myself am fairly new to Haskell and I'm trying to understand Monads better myself, but maybe this could help? http://user.cs.tu-berlin.de/~magr/pub/Transformers.en.html It's a little out of date and won't compile cleanly on newer instances of GHC without changing all the instances of Map.lookup ... to return $ fromJust Map.lookup, but once you make that small change it works fine. Also, I'm not familiar with the QuickCheck package, but I browsed through it quickly and Test.QuickCheck.Monadic caught my eye. Perhaps a State or StateT combined with IdM or PropertyM would do what you want? On Tue, Sep 15, 2009 at 5:56 PM, Alexander MacDonald <alex...@adobe.com>wrote: > Hi guys, I¹ve been using quickcheck for a while and I¹m having no problem > making generators for my data types, however recently I stumbled upon a > situation where I need to maintain State inside the quickcheck generator > functions. Here's a simple example, imagine I've got a basic language which > only has two features, variable definitions and assignments: > > type Script = [Statement] > > data Name = Name String > deriving (Show,Eq) > > data Statement = Def Name Int | Assign Name Name > deriving Show > > Generating random scripts is easy enough, just make each type an instance > of > Arbitrary with a suitable generator function, however I want to make sure > that the generated scripts are syntactically valid. In this case that means > no "Name" can be used in an "Assign" statement unless it has previously > been > defined by a "Def" statement. > > My knowledge of using monads is somewhat basic so I'm struggling to figure > out how to use the State monad with QuickCheck. I've pasted my current > effort on the web: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=9412 > > If anyone could spare a moment to glance at my code and give me a push in > the right direction that would be much appreciated! > > Thanks, > Alex Mac > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20090917/5ae175b9/attachment.html ------------------------------ _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners End of Beginners Digest, Vol 15, Issue 11 *****************************************