Lazy bind...

Thu, 1 Aug 2002 10:41:09 +0100

Hi Ken,
	Thankyou for having a look at this for me. I have implemented the
	type as:

	newtype (Error e,Monad m) => ParserT e s m a = PT {runParserT :: [s] -> m
(Result e s m a)}
	data (Error e) => Result e s m a = Accepted (m (Reply e s a)) | Rejected
	data (Error e) => Reply e s a = Ok [s] a | Empty | Fail e

	Having changed the instances of Monad/MonadPlus for this type, I can
	it works perfectly - I see how the nested Monad allows you to continue the
	computation in the 'bind' operator whilst still returning 'Accepted'.

	I think this is a lot better than the solution I had working, which
	a new subclass of Monad, defining the function 'lbind' to be just >>= for
	monads apart from IO where is was: lbind j k = unsafeInterleaveIO $ j >>=
	I then used lbind to bind the result of "runParserT (k x) cs'" in the '>>='
	function for ParserT...

	Thanks again,
	Keean Schupke
	Department of Electrical & Electronic Engineering,
	Imperial College London.

-----Original Message-----
[]On Behalf Of Ken Shan
Sent: 01 August 2002 06:08
Subject: Re: Lazy bind...

Yes!  Let me rephrase my earlier suggestion in terms of these actual

For reasons that will soon become clear, let me begin by rearranging
Result a bit:

    data Result x = Accepted x | Rejected
    newtype (Error e) => Parser e s a
	= Parser {runParser :: [s] -> Result (Reply e s a)}
    newtype (Error e, Monad m) => ParserT e s m a
	= ParserT {runParserT :: [s] -> m (Result (Reply e s a))}

(Here I have removed the constraint "Error e" from the definition of
Result.  I don't think it will cause you much trouble.)

Now, what about the following alternative definition of ParserT?

    newtype (Error e, Monad m) => ParserT e s m a
	= ParserT {runParserT :: [s] -> m (Result (m (Reply e s a)))}

Would it suit your purposes?

Edit this signature at
When was the last time you wrote your representative in government?
And, vote, for those who can't.