show (Yield x _) = "Yield " ++ show x

-instance Eq a => Eq (Stream a) where

+instance (Eq a) => Eq (Stream a) where

+instance (Ord a) => Ord (Stream a) where

-- The length hint in a Stream has two roles. If its value is zero,

-- we trust it, and treat the stream as empty. Otherwise, we treat it

-- as a hint: it should usually be accurate, so we use it when

-- | /O(n)/ Determines if two streams are equal.

eq :: (Eq a) => Stream a -> Stream a -> Bool

-eq (Stream next1 s1 _) (Stream next2 s2 _) = ~~cm~~p (next1 s1) (next2 s2)

+eq (Stream next1 s1 _) (Stream next2 s2 _) = loop (next1 s1) (next2 s2)

- cmp (Skip s1') (Skip s2') = cmp (next1 s1') (next2 s2')

- cmp (Skip s1') x2 = cmp (next1 s1') x2

- cmp x1 (Skip s2') = cmp x1 (next2 s2')

- cmp (Yield x1 s1') (Yield x2 s2') = x1 == x2 &&

- cmp (next1 s1') (next2 s2')

+ loop (Skip s1') (Skip s2') = loop (next1 s1') (next2 s2')

+ loop (Skip s1') x2 = loop (next1 s1') x2

+ loop x1 (Skip s2') = loop x1 (next2 s2')

+ loop (Yield x1 s1') (Yield x2 s2') = x1 == x2 &&

+ loop (next1 s1') (next2 s2')

{-# SPECIALISE eq :: Stream Char -> Stream Char -> Bool #-}

+cmp :: (Ord a) => Stream a -> Stream a -> Ordering

+cmp (Stream next1 s1 _) (Stream next2 s2 _) = loop (next1 s1) (next2 s2)

+ loop (Skip s1') (Skip s2') = loop (next1 s1') (next2 s2')

+ loop (Skip s1') x2 = loop (next1 s1') x2

+ loop x1 (Skip s2') = loop x1 (next2 s2')

+ loop (Yield x1 s1') (Yield x2 s2') =

+ EQ -> loop (next1 s1') (next2 s2')

+{-# SPECIALISE cmp :: Stream Char -> Stream Char -> Ordering #-}

streamList :: [a] -> Stream a

{-# INLINE streamList #-}