{-# LANGUAGE ExplicitForAll #-}
-- | Defines the Stream (pronounce: Sequence) type and related functions
module Data.Stream where
import Extra.Tuple as Tup
data Stream a = a :- Stream a
-- ^ Type for infinite lists
streamHead :: forall a. Stream a -> a
streamHead (x :- _) = x
-- ^ Like head, but for Stream
-- Gets the first element of a stream.
streamTail :: forall a. Stream a -> Stream a
streamTail (_ :- xs) = xs
-- ^ Like tail, but for Stream
-- Safer, since a Stream can't be empty
streamFromList :: forall a. [a] -> a -> Stream a
streamFromList [] a = streamUnfold dupe a
streamFromList (x:xs) a = x :- streamFromList xs a
-- ^ Makes a Stream from a finite list, repeats second argument when list is exhausted.
streamUnfold :: forall a b. (a -> (a, b)) -> a -> Stream b
streamUnfold f x =
let (a, b) = f x
in b :- streamUnfold f a
-- ^ Like unfoldr, but for Stream
-- Doesn't require the Maybe type in the signature,
-- since a Stream never ends.
-- No marking of unfold direction in the name,
-- since you can't build Streams from the right.
streamCycle :: forall a. [a] -> Maybe (Stream a)
streamCycle [] = Nothing
streamCycle l = Just $ streamFromList (cycle l) undefined
-- ^ Like cycle, but for Stream
-- Safe, returns Nothing when the input is an empty list.