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
*****************************************

Reply via email to