Conduits: Is Source a valid instance of Monad?

Hi all, As you may have noticed, Michael Snoyman has been working on an alternative approach to I/O, called conduits. You can find it here: https://github.com/snoyberg/conduit When looking at the Source type (explained here: http://www.yesodweb.com/blog/2011/12/conduits), I noticed that they seem to behave "like lists", and naturally wondered if I could write a Monad instance for them. But first, let's have a brief look at the definition of Source: data SourceResult a = Open a | Closed data PreparedSource m a = PreparedSource { sourcePull :: ResourceT m (SourceResult a) , sourceClose :: ResourceT m () } newtype Source m a = Source { prepareSource :: ResourceT m (PreparedSource m a) } ResourceT deals with resource acquisition and releasing (making sure that all resources are released), and provides a an abstraction over IORef/STRef. For our purposes here, ResourceT is probably close enough to IO. So now the question again is, can we write a Monad instance for this? I have been able to write join (concatenate) and return (a source with a single non-repeated) element. https://gist.github.com/1525471 I _think_ it behaves properly like a Monad, but I'm not quite sure, and neither was Michael. Greg Weber then suggested bringing the question to this forum. What made the question difficult for me is that this would be a stateful Monad transformer, so I'm not quite sure how to test the Monad laws properly. There's a second part to this question: If Source turns out not to be a Monad, is it possibly a ZipList-like Applicative? And either way, which is more useful: The list-like or the ziplist-like instances (of Applicative/Monad)? Thank you, Aristid

Is there any follow up on this?
I was wondering what is the best way to sequence a number of sources
together. Anybody gave a further thought on this?
Regards,
Paul Liu
On Tue, Dec 27, 2011 at 3:45 PM, Aristid Breitkreuz
Hi all,
As you may have noticed, Michael Snoyman has been working on an alternative approach to I/O, called conduits. You can find it here:
https://github.com/snoyberg/conduit
When looking at the Source type (explained here: http://www.yesodweb.com/blog/2011/12/conduits), I noticed that they seem to behave "like lists", and naturally wondered if I could write a Monad instance for them. But first, let's have a brief look at the definition of Source:
data SourceResult a = Open a | Closed
data PreparedSource m a = PreparedSource { sourcePull :: ResourceT m (SourceResult a) , sourceClose :: ResourceT m () }
newtype Source m a = Source { prepareSource :: ResourceT m (PreparedSource m a) }
ResourceT deals with resource acquisition and releasing (making sure that all resources are released), and provides a an abstraction over IORef/STRef. For our purposes here, ResourceT is probably close enough to IO.
So now the question again is, can we write a Monad instance for this? I have been able to write join (concatenate) and return (a source with a single non-repeated) element.
https://gist.github.com/1525471
I _think_ it behaves properly like a Monad, but I'm not quite sure, and neither was Michael. Greg Weber then suggested bringing the question to this forum. What made the question difficult for me is that this would be a stateful Monad transformer, so I'm not quite sure how to test the Monad laws properly.
There's a second part to this question: If Source turns out not to be a Monad, is it possibly a ZipList-like Applicative? And either way, which is more useful: The list-like or the ziplist-like instances (of Applicative/Monad)?
Thank you,
Aristid
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Paul Liu

On Wed, Apr 4, 2012 at 4:48 AM, Paul Liu
Is there any follow up on this?
I was wondering what is the best way to sequence a number of sources together. Anybody gave a further thought on this?
I believe sequence sources together can already be done by `Monoid` instance.
Regards, Paul Liu
On Tue, Dec 27, 2011 at 3:45 PM, Aristid Breitkreuz
wrote: Hi all,
As you may have noticed, Michael Snoyman has been working on an alternative approach to I/O, called conduits. You can find it here:
https://github.com/snoyberg/conduit
When looking at the Source type (explained here: http://www.yesodweb.com/blog/2011/12/conduits), I noticed that they seem to behave "like lists", and naturally wondered if I could write a Monad instance for them. But first, let's have a brief look at the definition of Source:
data SourceResult a = Open a | Closed
data PreparedSource m a = PreparedSource { sourcePull :: ResourceT m (SourceResult a) , sourceClose :: ResourceT m () }
newtype Source m a = Source { prepareSource :: ResourceT m (PreparedSource m a) }
ResourceT deals with resource acquisition and releasing (making sure that all resources are released), and provides a an abstraction over IORef/STRef. For our purposes here, ResourceT is probably close enough to IO.
So now the question again is, can we write a Monad instance for this? I have been able to write join (concatenate) and return (a source with a single non-repeated) element.
https://gist.github.com/1525471
I _think_ it behaves properly like a Monad, but I'm not quite sure, and neither was Michael. Greg Weber then suggested bringing the question to this forum. What made the question difficult for me is that this would be a stateful Monad transformer, so I'm not quite sure how to test the Monad laws properly.
There's a second part to this question: If Source turns out not to be a Monad, is it possibly a ZipList-like Applicative? And either way, which is more useful: The list-like or the ziplist-like instances (of Applicative/Monad)?
Thank you,
Aristid
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Paul Liu
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Thanks! I failed to notice this instance declaration in the document.
But I'm still curious as to whether a Monad instance for Source makes
any sense, since in 4.0 all of Source/Conduit/Sink would share the
same implementation.
Regards,
Paul Liu
On Tue, Apr 3, 2012 at 6:25 PM, yi huang
On Wed, Apr 4, 2012 at 4:48 AM, Paul Liu
wrote: Is there any follow up on this?
I was wondering what is the best way to sequence a number of sources together. Anybody gave a further thought on this?
I believe sequence sources together can already be done by `Monoid` instance.
Regards, Paul Liu
On Tue, Dec 27, 2011 at 3:45 PM, Aristid Breitkreuz
wrote: Hi all,
As you may have noticed, Michael Snoyman has been working on an alternative approach to I/O, called conduits. You can find it here:
https://github.com/snoyberg/conduit
When looking at the Source type (explained here: http://www.yesodweb.com/blog/2011/12/conduits), I noticed that they seem to behave "like lists", and naturally wondered if I could write a Monad instance for them. But first, let's have a brief look at the definition of Source:
data SourceResult a = Open a | Closed
data PreparedSource m a = PreparedSource { sourcePull :: ResourceT m (SourceResult a) , sourceClose :: ResourceT m () }
newtype Source m a = Source { prepareSource :: ResourceT m (PreparedSource m a) }
ResourceT deals with resource acquisition and releasing (making sure that all resources are released), and provides a an abstraction over IORef/STRef. For our purposes here, ResourceT is probably close enough to IO.
So now the question again is, can we write a Monad instance for this? I have been able to write join (concatenate) and return (a source with a single non-repeated) element.
https://gist.github.com/1525471
I _think_ it behaves properly like a Monad, but I'm not quite sure, and neither was Michael. Greg Weber then suggested bringing the question to this forum. What made the question difficult for me is that this would be a stateful Monad transformer, so I'm not quite sure how to test the Monad laws properly.
There's a second part to this question: If Source turns out not to be a Monad, is it possibly a ZipList-like Applicative? And either way, which is more useful: The list-like or the ziplist-like instances (of Applicative/Monad)?
Thank you,
Aristid
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Paul Liu
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Paul Liu

In 0.4, Source technically has a Monad instance, but it's not really
useful in the same way the instance Aristid is referring to. In order
to get that instance, we would need to introduce a newtype wrapper.
On Wed, Apr 4, 2012 at 5:55 PM, Paul Liu
Thanks! I failed to notice this instance declaration in the document.
But I'm still curious as to whether a Monad instance for Source makes any sense, since in 4.0 all of Source/Conduit/Sink would share the same implementation.
Regards, Paul Liu
On Tue, Apr 3, 2012 at 6:25 PM, yi huang
wrote: On Wed, Apr 4, 2012 at 4:48 AM, Paul Liu
wrote: Is there any follow up on this?
I was wondering what is the best way to sequence a number of sources together. Anybody gave a further thought on this?
I believe sequence sources together can already be done by `Monoid` instance.
Regards, Paul Liu
On Tue, Dec 27, 2011 at 3:45 PM, Aristid Breitkreuz
wrote: Hi all,
As you may have noticed, Michael Snoyman has been working on an alternative approach to I/O, called conduits. You can find it here:
https://github.com/snoyberg/conduit
When looking at the Source type (explained here: http://www.yesodweb.com/blog/2011/12/conduits), I noticed that they seem to behave "like lists", and naturally wondered if I could write a Monad instance for them. But first, let's have a brief look at the definition of Source:
data SourceResult a = Open a | Closed
data PreparedSource m a = PreparedSource { sourcePull :: ResourceT m (SourceResult a) , sourceClose :: ResourceT m () }
newtype Source m a = Source { prepareSource :: ResourceT m (PreparedSource m a) }
ResourceT deals with resource acquisition and releasing (making sure that all resources are released), and provides a an abstraction over IORef/STRef. For our purposes here, ResourceT is probably close enough to IO.
So now the question again is, can we write a Monad instance for this? I have been able to write join (concatenate) and return (a source with a single non-repeated) element.
https://gist.github.com/1525471
I _think_ it behaves properly like a Monad, but I'm not quite sure, and neither was Michael. Greg Weber then suggested bringing the question to this forum. What made the question difficult for me is that this would be a stateful Monad transformer, so I'm not quite sure how to test the Monad laws properly.
There's a second part to this question: If Source turns out not to be a Monad, is it possibly a ZipList-like Applicative? And either way, which is more useful: The list-like or the ziplist-like instances (of Applicative/Monad)?
Thank you,
Aristid
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Paul Liu
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Paul Liu
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (4)
-
Aristid Breitkreuz
-
Michael Snoyman
-
Paul Liu
-
yi huang