I am playing with linkedlist problem in python challenge that require querying a next value (guess it be Int).
I create function for get the next value as follows
url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="
getNext :: Int -> IO Int
getNext x = do
rsp <- simpleHTTP (getRequest $ url ++ show x)
bdy <- getResponseBody rsp
let num = last $ splitWhen (==' ') bdy
return (read num::Int)
and it work fine (in ghci)
> getNext 12345
44827
> getNext 44827
45439
While I suppose to repeatedly call getNext until I found the answer, I think I should keep the history like I can do in non-monadic world so I can continue from the last value in case something fail.
> let nX x = x + 3
> :t nX
nX :: Num a => a -> a
> take 10 $ iterate nX 1
[1,4,7,10,13,16,19,22,25,28]
I think it should be a monadic lifted version of iterate and found iterateM_ from Control.Monad.Loops but it didn’t work as I expected. There is nothing shown (I think _ suffix mean discard the result but there is no iterateM)
> :t iterate
iterate :: (a -> a) -> a -> [a]
> :t iterateM_
iterateM_ :: Monad m => (a -> m a) -> a -> m b
Question is how can I get [Int] as in non-monadic iteration. I think I want a function that return IO [Int] to be able to pull-out and filter/process in my code like this
main = do
i <- getAllList
let answer = last i -- or could be a repeated converged value, don't know yet
putStrLn (show answer)
getAllList :: IO [Int]
If you want your function to terminate early, rather than give back an
infinite list of results, you will want to use
unfoldrMrather thaniterateM. This can be done with something like the following: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.
The
unfoldrMfunction can be found in themonad-loopspackage, but thelatest 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
unfoldrMthat you would want.This is how you might go about this using
Pipes, which will allow you todo the processing as a stream of results without resorting to lazy I/O.