<div><font face="courier new,monospace">Hi everyone... it&#39;s my newbie post!</font></div>
<div><font face="courier new,monospace"></font>&nbsp;</div>
<div><font face="courier new,monospace">I am trying to create a monad which allows computations to output data to a stream.&nbsp;&nbsp;(Probably such a thing already exists, but it&#39;s a good problem for my current skill level in Haskell)
<br>&nbsp;</font></div>
<div><font face="courier new,monospace">For example:<br></font></div>
<div><font face="courier new,monospace">streamDemo = do<br>&nbsp;&nbsp;&nbsp;&nbsp;output 1<br>&nbsp;&nbsp;&nbsp;&nbsp;output 2<br>&nbsp;&nbsp;&nbsp;&nbsp;output 5<br></font></div>
<div><font face="courier new,monospace">makelist streamDemo -- [1,2,5]<br></font></div>
<div><font face="courier new,monospace">I modelled my implementation around the state monad, but with a different execution model:</font></div>
<div><font face="Courier New"></font>&nbsp;</div>
<div><font face="courier new,monospace">class (Monad m) =&gt; MonadStream w m | m -&gt; w where<br>&nbsp;&nbsp;&nbsp;&nbsp;output :: w -&gt; m ()<br>&nbsp;&nbsp;&nbsp;&nbsp;run :: m a -&gt; s -&gt; (s -&gt; w -&gt; s) -&gt; s&nbsp;&nbsp;-- basically foldl on the stream values
<br>makelist m = reverse $ run m [] (flip (:))<br><br>-- s is the type of the object to stream, r is the return type<br>type StreamFunc s r = forall b. b -&gt; (b -&gt; s -&gt; b) -&gt; (r,b)<br>newtype Stream s r = Stream { run&#39; :: StreamFunc s r }
<br>instance Monad (Stream s) where<br>&nbsp;&nbsp;&nbsp;&nbsp;return r = Stream (\s _ -&gt; (r,s))<br>&nbsp;&nbsp;&nbsp;&nbsp;Stream m &gt;&gt;= k = Stream (\s f -&gt; let (r,s&#39;) = (m s f)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in run&#39; (k r) s&#39; f)<br>instance (MonadStream w) (Stream w) where
<br>&nbsp;&nbsp;&nbsp;&nbsp;output w = Stream (\s f -&gt; ((),f s w))<br>&nbsp;&nbsp;&nbsp;&nbsp;run m st f = snd $ run&#39; m st f<br>&nbsp;</font></div>
<div><font face="courier new,monospace">What I don&#39;t like is how makelist comes out.&nbsp;&nbsp;It feels wrong to need to use reverse, and that also means that infinite streams completely fail to work.&nbsp;&nbsp;But I think it&#39;s impossible to fix with&nbsp;the &quot;foldl&quot;-style&nbsp;&quot;run&quot;.&nbsp;&nbsp;Is there a better implementation of &quot;makelist&quot;&nbsp;possible with my current definition of &quot;run&quot;?&nbsp; If not, what type should &quot;run&quot; have so that it can work correctly?
</font></div>
<div><font face="courier new,monospace">&nbsp;</font></div>
<div><font face="courier new,monospace">As an example,&nbsp;I want to fix the implementation&nbsp;to make the following code work:</font></div>
<div><font face="courier new,monospace">fibs :: Stream Integer ()<br>fibs =&nbsp; fibs&#39; 0 1</font></div>
<div><font face="courier new,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where fibs&#39; x y = output y &gt;&gt;&nbsp;fibs&#39; y (x+y)<br></font><font face="courier new,monospace"></font></div>
<div><font face="Courier New">fiblist :: [Integer]</font>&nbsp;</div>
<div><font face="courier new,monospace">fiblist = makelist fibs</font></div>
<div><font face="courier new,monospace"></font>&nbsp;</div>
<div><font face="courier new,monospace">take 5 fiblist&nbsp;-- [1,1,2,3,5], but currently goes into an&nbsp;infinite loop</font></div>
<div><font face="courier new,monospace"></font>&nbsp;</div>
<div><font face="courier new,monospace">Thanks,</font></div>
<div><font face="courier new,monospace">&nbsp; -- ryan</font></div>