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 unfoldrM rather than
iterateM. This can be done with something like the following:
url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="
start = 12345
stop = 10000
shouldStop :: Int -> Bool
shouldStop x = x == stop
getNext :: Int -> IO (Maybe (Int, Int))
getNext prev
| shouldStop prev = return Nothing
| otherwise = do
rsp <- simpleHTTP (getRequest $ url ++ show prev)
bdy <- getResponseBody rsp
let num = read $ last $ splitWhen (==' ') bdy :: Int
print (prev, num)
return $ Just (num, num)
getAllList :: IO [Int]
getAllList = unfoldrM getNext start
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 unfoldrM function can be found in the monad-loops 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 unfoldrM that you would want.
-- |See 'Data.List.unfoldr'. This is a monad-friendly version of that.
unfoldrM :: (Monad m) => (a -> m (Maybe (b,a))) -> a -> 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) => (a -> m (Maybe (b,a))) -> a -> m (f b)
unfoldrM' f z = go z
where go z = do
x <- f z
case x of
Nothing -> return mzero
Just (x, z) -> do
xs <- go z
return (return x `mplus` xs)
This is how you might go about this using Pipes, which will allow you to
do the processing as a stream of results without resorting to lazy I/O.
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) => Int -> () -> Producer p String IO ()
grabber start () = runIdentityP $ loop $ show start where
loop x = do
-- Grab the next value
x' <- 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) => () -> Consumer p a IO r
printer () = runIdentityP $ forever $ do
a <- request () -- Consume a value
lift $ putStrLn $ "Received a value: " ++ show a
getNext :: String -> IO String
getNext prev = do
rsp <- simpleHTTP (getRequest $ url ++ prev)
bdy <- getResponseBody rsp
let num = last $ splitWhen (== ' ') bdy
return num
main = runProxy $ grabber start >-> printer
So what you want is basically
iterateM :: Monad m => (a -> m a) -> a -> m [a]
iterateM action a = do
a' <- action a
liftM (a':) $ iterateM action a'
The problem is that this doesn't work lazily as one might expect: since the monadic bind is strict, you're stuck in an infinite loop, even if you only want to evaluate a finite number of as.
Related
I'm a beginner in OCaml and algorithms.
I'm trying to get the number of 5 digits numbers with no repeating digits bigger than 12345.
Here is what I did in OCaml, I tried to make as tail recursive as possible, and I also used streams. But still, due to size, it stack overflowed:
type 'a stream = Eos | StrCons of 'a * (unit -> 'a stream)
let rec numberfrom n= StrCons (n, fun ()-> numberfrom (n+1))
let nats = numberfrom 1
let rec listify st n f=
match st with
|Eos ->f []
|StrCons (m, a) ->if n=1 then f [m] else listify (a ()) (n-1) (fun y -> f (m::y))
let rec filter (test: 'a-> bool) (s: 'a stream) : 'a stream=
match s with
|Eos -> Eos
|StrCons(q,w) -> if test q then StrCons(q, fun ()->filter test (w ()))
else filter test (w ())
let rec check_dup l=
match l with
| [] -> false
| h::t->
let x = (List.filter (fun x -> x = h) t) in
if (x == []) then
check_dup t
else
true;;
let digits2 d =
let rec dig acc d =
if d < 10 then d::acc
else dig ((d mod 10)::acc) (d/10) in
dig [] d
let size a=
let rec helper n aa=
match aa with
|Eos-> n
|StrCons (q,w) -> helper (n+1) (w())
in helper 0 a
let result1 = filter (fun x -> x<99999 && x>=12345 && (not (check_dup (digits2 x)))) nats
(* unterminating : size result1 *)
(*StackOverflow: listify result1 10000 (fun x->x) *)
I can't reproduce your reported problem. When I load up your code I see this:
# List.length (listify result1 10000 (fun x -> x));;
- : int = 10000
# List.length (listify result1 26831 (fun x -> x));;
- : int = 26831
It's possible your system is more resource constrained than mine.
Let me just say that the usual way to code a tail recursive function is to build the list up in reverse, then reverse it at the end. That might look something like this:
let listify2 st n =
let rec ilist accum st k =
match st with
| Eos -> List.rev accum
| StrCons (m, a) ->
if k = 1 then List.rev (m :: accum)
else ilist (m :: accum) (a ()) (k - 1)
in
if n = 0 then []
else ilist [] st n
You still have the problem that listify doesn't terminate if you ask for more elements than there are in the stream. It might be better to introduce a method to detect the end of the stream and return Eos at that point. For example, the filter function might accept a function that returns three possible values (the element should be filtered out, the element should not be filtered out, the stream should end).
The problem is that the size of your stream result1 is undefined.
Indeed, nats is an never-ending stream: it never returns Eos.
However, filtering a never-ending stream results in another never-ending stream
since a filtered stream only returns Eos after the underlying stream does so:
let rec filter (test: 'a-> bool) (s: 'a stream) : 'a stream=
match s with
| Eos -> Eos
| StrCons(q,w) -> if test q then StrCons(q, fun ()->filter test (w ()))
else filter test (w ())
Consequently, size result1 is stuck trying to reach the end of integers.
Note also that, in recent version of the standard library, your type stream is called Seq.node.
Implementing Haskell's take and drop functions using foldl.
Any suggestions on how to implement take and drop functions using foldl ??
take x ls = foldl ???
drop x ls = foldl ???
i've tried these but it's showing errors:
myFunc :: Int -> [a] -> [a]
myFunc n list = foldl func [] list
where
func x y | (length y) > n = x : y
| otherwise = y
ERROR PRODUCED :
*** Expression : foldl func [] list
*** Term : func
*** Type : a -> [a] -> [a]
*** Does not match : [a] -> [a] -> [a]
*** Because : unification would give infinite type
Can't be done.
Left fold necessarily diverges on infinite lists, but take n does not. This is so because left fold is tail recursive, so it must scan through the whole input list before it can start the processing.
With the right fold, it's
ntake :: Int -> [a] -> [a]
ntake 0 _ = []
ntake n xs = foldr g z xs 0
where
g x r i | i>=n = []
| otherwise = x : r (i+1)
z _ = []
ndrop :: Int -> [a] -> [a]
ndrop 0 xs = xs
ndrop n xs = foldr g z xs 0 xs
where
g x r i xs#(_:t) | i>=n = xs
| otherwise = r (i+1) t
z _ _ = []
ndrop implements a paramorphism nicely and faithfully, up to the order of arguments to the reducer function g, giving it access to both the current element x and the current list node xs (such that xs == (x:t)) as well as the recursive result r. A catamorphism's reducer has access only to x and r.
Folds usually encode catamorphisms, but this shows that right fold can be used to code up a paramorphism just as well. It's universal that way. I think it is beautiful.
As for the type error, to fix it just switch the arguments to your func:
func y x | ..... = .......
The accumulator in the left fold comes as the first argument to the reducer function.
If you really want it done with the left fold, and if you're really sure the lists are finite, two options:
ltake n xs = post $ foldl' g (0,id) xs
where
g (i,f) x | i < n = (i+1, f . (x:))
| otherwise = (i,f)
post (_,f) = f []
rltake n xs = foldl' g id xs r n
where
g acc x = acc . f x
f x r i | i > 0 = x : r (i-1)
| otherwise = []
r _ = []
The first counts from the left straight up, potentially stopping assembling the prefix in the middle of the full list traversal that it does carry to the end nevertheless, being a left fold.
The second also traverses the list in full turning it into a right fold which then gets to work counting down from the left again, being able to actually stop working as soon as the prefix is assembled.
Implementing drop this way is bound to be (?) even clunkier. Could be a nice exercise.
I note that you never specified the fold had to be over the supplied list. So, one approach that meets the letter of your question, though probably not the spirit, is:
sillytake :: Int -> [a] -> [a]
sillytake n xs = foldl go (const []) [1..n] xs
where go f _ (x:xs) = x : f xs
go _ _ [] = []
sillydrop :: Int -> [a] -> [a]
sillydrop n xs = foldl go id [1..n] xs
where go f _ (_:xs) = f xs
go _ _ [] = []
These each use left folds, but over the list of numbers [1..n] -- the numbers themselves are ignored, and the list is just used for its length to build a custom take n or drop n function for the given n. This function is then applied to the original supplied list xs.
These versions work fine on infinite lists:
> sillytake 5 $ sillydrop 5 $ [1..]
[6,7,8,9,10]
Will Ness showed a nice way to implement take with foldr. The least repulsive way to implement drop with foldr is this:
drop n0 xs0 = foldr go stop xs0 n0
where
stop _ = []
go x r n
| n <= 0 = x : r 0
| otherwise = r (n - 1)
Take the efficiency loss and rebuild the whole list if you have no choice! Better to drive a nail in with a screwdriver than drive a screw in with a hammer.
Both ways are horrible. But this one helps you understand how folds can be used to structure functions and what their limits are.
Folds just aren't the right tools for implementing drop; a paramorphism is the right tool.
You are not too far. Here are a pair of fixes.
First, note that func is passed the accumulator first (i.e. a list of a, in your case) and then the list element (an a). So, you need to swap the order of the arguments of func.
Then, if we want to mimic take, we need to add x when the length y is less than n, not greater!
So we get
myFunc :: Int -> [a] -> [a]
myFunc n list = foldl func [] list
where
func y x | (length y) < n = x : y
| otherwise = y
Test:
> myFunc 5 [1..10]
[5,4,3,2,1]
As you can see, this is reversing the string. This is because we add x at the front (x:y) instead of at the back (y++[x]). Or, alternatively, one could use reverse (foldl ....) to fix the order at the end.
Also, since foldl always scans the whole input list, myFunc 3 [1..1000000000] will take a lot of time, and myFunc 3 [1..] will fail to terminate. Using foldr would be much better.
drop is more tricky to do. I don't think you can easily do that without some post-processing like myFunc n xs = fst (foldl ...) or making foldl return a function which you immediately call (which is also a kind of post-processing).
I am trying to recursively make a list of random numbers that uses the previous value to get the next (so recursion is required instead of map or fold, and also I prefer to make it explicit unless map/foldr makes it ridiculously simple in comparison).
Using a pure PRNG this is very straightforward and idiomatic, in my opinion (puregaussian uses System.Random to generate a normal variate and has type puregaussian :: System.Random.RandomGen t => t -> Double -> Double -> (Double, t)).
purecurse :: System.Random.RandomGen t => t -> Double -> [Double] -> [Double]
purecurse gen current [] = []
purecurse gen current (x:xs) = let (rand, gen2) = puregaussian gen 0 1
next = current + rand
in current:purecurse gen2 next xs
Unfortunately, pure PRNGs don't seem do be as well developed in Haskell as the monadic ones, so I want to do the same thing using a library like random-fu or mwc-probability, and the solutions I found to work are either unidiomatic, not as concise, or both.
Here's a solution using do notation that works, and why I'm not satisfied with it:
import Control.Monad.Primitive
import System.Random.MWC.Probability
recurse :: PrimMonad m => Gen (PrimState m) -> [Double] -> [Double] -> m [Double]
recurse gen history#(current:_) [] = return history
recurse gen history#(current:_) (x:xs) = do
rand <- (sample (normal 0 1) gen)
let next = current + rand
recurse gen (next:history) xs
First of all I would rather use >>= than do notation, but I couldn't find a way of binding the rand variable that has type m Double and then lifting it to get m [Double] at the end case. There doesn't seem to be a lot of documentation (that I could find) or examples on how to do something like that.
I thought maybe it would be necessary to nest the (>>=) operators, but that could make the function extremely complicated or unreadable. If that is the tradeoff, maybe do notation is just cleaner, but I didn't manage to make even that work and would like to know how to.
Second, the function requires the entire list to be passed on at each call, and gives the list back in reverse (and just switching next and history breaks it).
So. I would like to be able to pass the initial state and a list to recurse over that returns a monadic list of values.
The main question I would like help with is: is there a Haskell idiomatic way of writing such a recursion of monadic values resulting in a monadic list that is similar to the structure of a pure function?
The main question I would like help with is: is there a Haskell idiomatic way of writing such a recursion of monadic values resulting in a monadic list that is similar to the structure of a pure function?
You can do it in two steps. Have your recursive function return a list of "monadic actions", then compose / sequence those actions.
Lets consider a simpler but analogous function to yours, for ease of presentation. Instead of randomness lets consider input. The list you recourse over is there for size only (content is ignored) so lets just use an integer.
rc :: Int -> [Double] -> IO [Double]
rc 0 h = return h
rc n h#(cr:_) = do rand <- readLn :: IO Double
let nx = cr + rand
rc (n-1)(nx:h)
Here is a similar alternative that works the way you wants
rc' :: Int -> Double -> IO [Double]
rc' 0 cr = return []
rc' n cr = do rand <- readLn :: IO Double
let nx = cr + rand
xs <- rc' (n-1) nx
return (nx : xs)
And here without do notation
rc'' :: Int -> Double -> IO [Double]
rc'' 0 cr = return []
rc'' n cr = (readLn :: IO Double) >>= (\rand ->
let nx = cr + rand
in (rc'' (n-1) nx) >>= (\xs ->
return (nx : xs)))
In any case, another thing you can do is abstract away pieces of code, rather than have a monolithic presentation.
In each step you require the current value to generate a new one. So a step is a function of type Double -> IO Double. And this is a pretty neat type, fundamental in the world of monads. You can bind values to a step via x >>= step or compose two steps with step1 >=> step2. So lets go with it.
step :: Double -> IO Double
step cr = do rand <- readLn :: IO Double
return (cr + rand)
It's very easy to understand. You 'generate' a number, add the current one and return the result. And you want to do n such steps, so make a list of steps.
steps :: Int -> [Double -> IO Double]
steps n = replicate n step
Now you can choose how to combine them. For instance it would be very natural to fold a list of steps with >=>. You would get this,
runSteps :: Int -> Double -> IO Double
runSteps n = foldr (>=>) return (steps n)
It's close to what you want but only returns the final result, rather than accumulate the generated values at each step. Below is a (restricted) type of (>=>) and the type of the operator (*=>) we want.
(>=>) :: Monad m => (a -> m a) -> (b -> m a) -> a -> m a
(*=>) :: Monad m => (a -> m a) -> (a -> m [a]) -> a -> m [a]
The definition is,
(*=>) :: Monad m => (a -> m a) -> (a -> m [a]) -> a -> m [a]
(*=>) ac uc c = do x <- ac c
xs <- uc x
return (x:xs)
I actually think this encapsulates the bit you didn't particularly like. Now we abstracted it away to this isolated piece of code. Even away from the recursive calls. And finally we just fold to execute the steps.
execSteps :: Int -> Double -> IO [Double]
execSteps n = foldr (*=>) (\x -> return []) (steps n)
This function differs from the original one in the initial input being a Double rather than a [Double]. But this is the type that makes sense. You'd just be passing a single wrapped double in the original function. And it accumulates the elements in the 'right' order as you requested.
is there a Haskell idiomatic way of writing such a recursion of
monadic values resulting in a monadic list that is similar to the
structure of a pure function
Usually, when need apply a monadic values to a pure function, Applicative operator, such as <$>, <*> may be helpful.
In particular, for list construction, it is often apply operator (:) in recursive way to build a list, like
f [] = []
f (x:xs) = x : f xs
in prefix way:
(:) x (f xs)
However, (:) is pure function, not accept monadic value by default, but the good new is, every data type which is instance of Monad, it also be an instance of Applicative. with help of Applicative operator mentioned above, monadic value can be applied to pure function without any change. For example,
(:) <$> (pure x) <*> (pure .f) xs
will return a monadic List instead of pure list.
Return to your question, personally, I think your solution in question is already almost a idiomatic way to do that (since it is simple and readable) except always append next random value at the head of history.
As you said, the list back in reverse and worse, when the history list has old random value already, it is inconvenient to find out which is new add to it.
To solve it, it can be modified slightly as:
recurse :: PrimMonad m => Gen (PrimState m) -> [Double] -> [Double] -> m [Double]
recurse gen history [] = return history
recurse gen history (x:xs) = do rand <- (sample (normal 0 1) gen)
let next = (last history) + rand
recurse gen (history ++ [next]) xs
It make sense, if the last element of history is the newest random value.
However, the different between (:) and (++) is: (:) is O(1), but (++) is O(N), where the N is the length of history list. (and last history is also O(N) instead of O(1)).
To archive an efficient solution, a helper function may need to introduce, say, newHistory, to construct a new list of random value as:
newHistory::PrimMonad m=>Gen(PrimState m)->m Double->[Double]->m [Double]
newHistory _ _ [] = return []
newHistory gen current (x:xs) = let next = (+) <$> current <*> sample (normal 0 1) gen
in (:) <$> next <*> newHistory gen next xs
As said before, with help of Applicative operator, the syntax look like pure function, except apply function in prefix way and use Applicative operator.
And then append back to the original history list as:
(++) <$> pure history <*> newHistory gen (pure $ last history) xs
And the Applicative version of recurse function look like:
recurse2::PrimMonad m=>Gen(PrimState m)->[Double]->[Double]->m [Double]
recurse2 gen history xs =
(++) <$> pure history <*> newHistory gen (pure $ last history) xs
where newHistory::PrimMonad m=>Gen(PrimState m)->m Double->[Double]->m [Double]
newHistory _ _ [] = return []
newHistory gen current (x:xs) =
let next = (+) <$> current <*> sample (normal 0 1) gen
in (:) <$> next <*> newHistory gen next xs
In situations like this, I usually jump straight to using a streaming library with a suitably list-like interface, like streaming. They allow a more natural translation from pure code to monadic, and have the added benefit that you aren't required to construct/consume all of the results at once, but instead incrementally, just as with pure lists.
I'm not sure what purecurse is doing, but it could be written as
import Streaming
import qualified Streaming.Prelude as S
recurse :: PrimMonad m
=> Gen (PrimState m)
-> Double
-> [Double]
-> Stream (Of Double) m ()
recurse gen current [] =
return ()
recurse gen current (x:xs) =
S.yield current *> -- (*>) and (>>) work like concatenation for pure lists
lift (sample (normal 0 1) gen) >>= \rand ->
recurse gen (current + rand) xs
Or, more naturally using do-notation, as:
recurse :: PrimMonad m
=> Gen (PrimState m)
-> Double
-> [Double]
-> Stream (Of Double) m ()
recurse gen current [] =
return ()
recurse gen current (x:xs) =
do S.yield current -- (*>) and (>>) work like concatenation for pure lists
rand <- lift $ sample (normal 0 1) gen
recurse gen (current + rand) xs
Now you can use function like S.take to generate/extract only parts of the result. If you want to get the whole list, you can use S.toList_.
Your issue seems to lie with do-notation and monads. You're assuming there's much more magic going on than there actually is: learning how the desugaring works will help you out here.
Anyway, let's try and convert the non-monadic version into the monadic one step-by-step. First, the type signature:
recurse :: PrimMonad m => Gen (PrimState m) -> Double -> [Double] -> m [Double]
I'm not sure why you had [Double] as the second parameter in your version: we want to change as little as possible from the original. The first clause, then:
purecurse gen current [] = []
-- Goes to:
recurse gen current [] = return []
Again, we're changing as little as possible: no effects were happening in this clause in your pure code, so no effects should be happening here, either. You got the next two lines right:
purecurse gen current (x:xs) = let (rand, gen2) = puregaussian gen 0 1
next = current + rand
-- Goes to:
recurse gen current (x:xs) = do rand <- (sample (normal 0 1) gen)
let next = current + rand
But the last one tripped you up. Ideally, we would write:
in current:purecurse gen2 next xs
-- Goes to:
current:recurse gen next xs
But it doesn't work! What's more, you get a confusing error:
• Couldn't match type ‘Double’ with ‘[Double]’
Expected type: m [Double]
Actual type: [Double]
This is probably what led you down the wrong path. The issue has nothing to do with the lists: it's to do with the m (the encapsulating monad). When you write current : xs, xs has to be a list: in this example, it's actually a m [Double], or a list wrapped in the monad. There's two ways to solve the problem (which are both equivalent). We could unwrap the list, using do notation again:
rest <- recurse gen next xs
return (current : rest)
Or we could lift the function current : to work inside the monad:
fmap (current:) (recurse gen next xs)
I'm making a function readUntil that reads lines from user. Reading stops when f returns True for a line. Then the lines are returned as a list (the line that returned True is not included in that list). Here's what I have at the moment (some really raw/pseudo code now, excuse me):
readUntil :: (String -> Bool) -> IO [String]
readUntil f = fmap reverse (go []) where
go xs = do
x <- getLine
if f = True then return xs
else go (x : xs)
I would also like to make readUntil recursive (or implement a recursive helper function).
I've included a small example below. You're pretty much at the solution. The important bit is just remembering how you'd generate a non-monad recusive list, then just putting that in the monad.
collectUntil :: (Monad m) => m a -> (a -> Bool) -> m [a]
collectUntil act f = do
x <- act
if f x
then return []
else (x:) <$> collectUntil act f
readUntil :: (String -> Bool) -> IO [String]
readUntil = collectUntil getLine
The function search below searches for two inputs which have the same output under some function. During the search it iterates over the input list xs twice, and this input list could be very large, e.g. [0..1000000000]. I'd rather use memory for storing the HashSet created by collision rather than storing the elements of xs, and my understanding is that even though xs could be lazily computed it would be kept around in case it was needed for the call to find.
Questions:
is this understanding correct?
if I keep it as a list is there a way I can have xs recomputed if it is passed to find?
is there an alternative data structure I can use for xs which allows me to control the space used? xs is just used to specify which inputs to check.
Note that there are no type restrictions on xs - it can be a collection of any type.
import Data.HashSet as Set
import Data.Hashable
import Data.List
search :: (Hashable b, Eq b) => (a->b) -> [a] -> Maybe (a,a)
search h xs =
do x0 <- collision h xs
let h0 = h x0
x1 <- find (\x -> (h x) == h0) xs
return (x0,x1)
collision :: (Hashable b, Eq b) => (a->b) -> [a] -> Maybe a
collision h xs = go Set.empty xs
where
go s [] = Nothing
go s (x:xs) =
if y `Set.member` s
then Just x
else go (Set.insert y s) xs
where y = h x
main = print $ search (\x -> x `mod` 21) ([10,20..2100] :: [Int])
I answered basically this question here: https://stackoverflow.com/a/6209279/371753
Here's the relevant code.
import Data.Stream.Branching(Stream(..))
import qualified Data.Stream.Branching as S
import Control.Arrow
import Control.Applicative
import Data.List
data UM s a = UM (s -> Maybe a) deriving Functor
type UStream s a = Stream (UM s) a
runUM s (UM f) = f s
liftUM x = UM $ const (Just x)
nullUM = UM $ const Nothing
buildUStream :: Int -> Int -> Stream (UM ()) Int
buildUStream start end = S.unfold (\x -> (x, go x)) start
where go x
| x < end = liftUM (x + 1)
| otherwise = nullUM
usToList x = unfoldr (\um -> (S.head &&& S.tail) <$> runUM () um) x
Long story short, instead of passing around a list, pass around a data type that describes how to generate a list. Now you can write functions directly over the stream, or you can use the usToList function to use the list functions you already have.