I have this code where these functions have been made:
The code is as follows:
data Stream a = Cons a (Stream a)
streamToList :: Stream a -> [a]
streamToList (Cons x xs) = x : streamToList xs
streamIterate :: (a -> a) -> a -> Stream a
streamIterate f x = Cons x (streamIterate f (f x))
streamIterLeave :: Stream a -> Stream a -> Stream a
streamIterLeave (Cons x xs) ys = Cons x (streamIterLeave ys xs)
Now what I am having problems with is I have no idea how to check this code on ghci. To be more specific, how do I input a stream into the command line?
For example I tried streamToList [1,2,3] ; streamToList (1,2,3); streamToList 1,2,3 and none of them seem to be working.
Help is very much appreciated!
Several ways. The simplest is just using undefined:
> take 2 $ streamToList $ Cons 1 $ Cons 2 undefined
[1,2]
You can defined named streams at the prompt,
> let { one = Cons 1 two ; two = Cons 2 one }
or with multi-line input,
> :{
| one = Cons 1 two
| two = Cons 2 one
| :}
> take 5 $ streamToList one
[1,2,1,2,1]
and you can use your streamIterate as shown in the comments or use foldr to create your streams from lists,
> take 5 $ streamToList $ streamIterate (+1) 0
[0,1,2,3,4]
> listToStream xs = foldr Cons undefined xs
> intS = listToStream [1..]
> take 5 $ streamToList intS
[1,2,3,4,5]
Having defined listToStream you can further easily define
> mapStream f s = listToStream . map f . streamToList $ s
> intsStream = x where { x = Cons 1 $ mapStream (1+) x }
> take 5 $ streamToList intsStream
[1,2,3,4,5]
> zipStr s1 s2 = listToStream $ zip (streamToList s1) (streamToList s2)
> zipStrWith f s1 s2 = mapStream (uncurry f) (zipStr s1 s2)
> addStreams s1 s2 = zipStrWith (+) s1 s2
> fibS = let {a = Cons 0 b; b = Cons 1 c; c = addStreams a b} in a
> take 15 $ streamToList fibS
[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]
etc. etc. etc.
as dfeuer mentions in the comments, listToStream above is a bit bogus -- it allows for invalid (i.e. finite) lists as its argument. It's OK for playing with it at the REPL, but not in general.
It could be better to "pull the bogosity out to the call site", by defining
> :{
| (+++) :: [a] -> Stream a -> Stream a
| xs +++ ys = foldr Cons ys xs
| :}
allowing us to define streams like
> good = [1..] +++ undefined
> bad = [1..10] +++ undefined
where the problem, if present, is more immediately apparent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With