Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you want your function to terminate early, rather than give back an infinite list of results, you will want to use <code>unfoldrM</code> rather than <code>iterateM</code>. This can be done with something like the following:</p> <pre><code>url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=" start = 12345 stop = 10000 shouldStop :: Int -&gt; Bool shouldStop x = x == stop getNext :: Int -&gt; IO (Maybe (Int, Int)) getNext prev | shouldStop prev = return Nothing | otherwise = do rsp &lt;- simpleHTTP (getRequest $ url ++ show prev) bdy &lt;- getResponseBody rsp let num = read $ last $ splitWhen (==' ') bdy :: Int print (prev, num) return $ Just (num, num) getAllList :: IO [Int] getAllList = unfoldrM getNext start </code></pre> <p>This will allow you to define a stopping criteria so that the loop can terminate, but you will not receive results back until the termination criteria has been met.</p> <p>The <code>unfoldrM</code> function can be found in the <code>monad-loops</code> package, but the latest version keeps reusing the original seed rather than the one produced by the generator function (I believe this has been fixed but not uploaded to Hackage). This is the version of <code>unfoldrM</code> that you would want.</p> <pre><code>-- |See 'Data.List.unfoldr'. This is a monad-friendly version of that. unfoldrM :: (Monad m) =&gt; (a -&gt; m (Maybe (b,a))) -&gt; a -&gt; m [b] unfoldrM = unfoldrM' -- |See 'Data.List.unfoldr'. This is a monad-friendly version of that, with a -- twist. Rather than returning a list, it returns any MonadPlus type of your -- choice. unfoldrM' :: (Monad m, MonadPlus f) =&gt; (a -&gt; m (Maybe (b,a))) -&gt; a -&gt; m (f b) unfoldrM' f z = go z where go z = do x &lt;- f z case x of Nothing -&gt; return mzero Just (x, z) -&gt; do xs &lt;- go z return (return x `mplus` xs) </code></pre> <p>This is how you might go about this using <code>Pipes</code>, which will allow you to do the processing as a stream of results without resorting to lazy I/O.</p> <pre><code>import Network.HTTP import Control.Monad import Data.List.Split import Control.Monad import Control.Proxy url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=" grabber :: (Proxy p) =&gt; Int -&gt; () -&gt; Producer p String IO () grabber start () = runIdentityP $ loop $ show start where loop x = do -- Grab the next value x' &lt;- lift $ getNext x -- Send it down stream respond x' -- Keep grabbing loop x' -- Just prints the values recieved from up stream printer :: (Proxy p, Show a) =&gt; () -&gt; Consumer p a IO r printer () = runIdentityP $ forever $ do a &lt;- request () -- Consume a value lift $ putStrLn $ "Received a value: " ++ show a getNext :: String -&gt; IO String getNext prev = do rsp &lt;- simpleHTTP (getRequest $ url ++ prev) bdy &lt;- getResponseBody rsp let num = last $ splitWhen (== ' ') bdy return num main = runProxy $ grabber start &gt;-&gt; printer </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload