@@ -41,9 +41,12 @@ instance Show a => Show (Step s a)
4141 show (Skip _) = "Skip"
4242 show (Yield x _) = "Yield " ++ show x
4343
44−instance Eq a => Eq (Stream a) where
44+instance (Eq a) => Eq (Stream a) where
4545 (==) = eq
4646
47+instance (Ord a) => Ord (Stream a) where
48+ compare = cmp
49+
4750-- The length hint in a Stream has two roles. If its value is zero,
4851-- we trust it, and treat the stream as empty. Otherwise, we treat it
4952-- as a hint: it should usually be accurate, so we use it when
@@ -76,19 +79,35 @@ empty = Stream next () 0
7679
7780-- | /O(n)/ Determines if two streams are equal.
7881eq :: (Eq a) => Stream a -> Stream a -> Bool
79−eq (Stream next1 s1 _) (Stream next2 s2 _) = cmp (next1 s1) (next2 s2)
82+eq (Stream next1 s1 _) (Stream next2 s2 _) = loop (next1 s1) (next2 s2)
8083 where
81− cmp Done Done = True
82− cmp (Skip s1') (Skip s2') = cmp (next1 s1') (next2 s2')
83− cmp (Skip s1') x2 = cmp (next1 s1') x2
84− cmp x1 (Skip s2') = cmp x1 (next2 s2')
85− cmp Done _ = False
86− cmp _ Done = False
87− cmp (Yield x1 s1') (Yield x2 s2') = x1 == x2 &&
88− cmp (next1 s1') (next2 s2')
84+ loop Done Done = True
85+ loop (Skip s1') (Skip s2') = loop (next1 s1') (next2 s2')
86+ loop (Skip s1') x2 = loop (next1 s1') x2
87+ loop x1 (Skip s2') = loop x1 (next2 s2')
88+ loop Done _ = False
89+ loop _ Done = False
90+ loop (Yield x1 s1') (Yield x2 s2') = x1 == x2 &&
91+ loop (next1 s1') (next2 s2')
8992{-# INLINE [0] eq #-}
9093{-# SPECIALISE eq :: Stream Char -> Stream Char -> Bool #-}
9194
95+cmp :: (Ord a) => Stream a -> Stream a -> Ordering
96+cmp (Stream next1 s1 _) (Stream next2 s2 _) = loop (next1 s1) (next2 s2)
97+ where
98+ loop Done Done = EQ
99+ loop (Skip s1') (Skip s2') = loop (next1 s1') (next2 s2')
100+ loop (Skip s1') x2 = loop (next1 s1') x2
101+ loop x1 (Skip s2') = loop x1 (next2 s2')
102+ loop Done _ = LT
103+ loop _ Done = GT
104+ loop (Yield x1 s1') (Yield x2 s2') =
105+ case compare x1 x2 of
106+ EQ -> loop (next1 s1') (next2 s2')
107+ other -> other
108+{-# INLINE [0] cmp #-}
109+{-# SPECIALISE cmp :: Stream Char -> Stream Char -> Ordering #-}
110+
92111streamList :: [a] -> Stream a
93112{-# INLINE streamList #-}
94113streamList [] = empty