@@ -187,6 +187,9 @@ cons !w (Stream next0 s0 len) = Stream next (C1 s0) (len+1)
187187 Yield x s' -> Yield x (C0 s')
188188{-# INLINE [0] cons #-}
189189
190+data Snoc a = N
191+ | J !a
192+
190193-- | /O(n)/ Adds a character to the end of a stream.
191194snoc :: Stream Char -> Char -> Stream Char
192195snoc (Stream next0 xs0 len) w = Stream next (J xs0) (len+1)
@@ -762,24 +765,27 @@ take n0 (Stream next0 s0 len) =
762765 Yield x s' -> Yield x ((n-1) :*: s')
763766{-# INLINE [0] take #-}
764767
768+data Drop a s = NS !s
769+ | JS !a !s
770+
765771-- | /O(n)/ drop n, applied to a stream, returns the suffix of the
766772-- stream after the first @n@ characters, or the empty stream if @n@
767773-- is greater than the length of the stream.
768774drop :: Integral a => a -> Stream Char -> Stream Char
769775drop n0 (Stream next0 s0 len) =
770− Stream next (J n0 :*: s0) (len - fromIntegral (max 0 n0))
776+ Stream next (JS n0 s0) (len - fromIntegral (max 0 n0))
771777 where
772778 {-# INLINE next #-}
773− next (J n :*: s)
774− | n <= 0 = Skip (N :*: s)
779+ next (JS n s)
780+ | n <= 0 = Skip (NS s)
775781 | otherwise = case next0 s of
776782 Done -> Done
777− Skip s' -> Skip (J n :*: s')
778− Yield _ s' -> Skip (J (n-1) :*: s')
779− next (N :*: s) = case next0 s of
783+ Skip s' -> Skip (JS n s')
784+ Yield _ s' -> Skip (JS (n-1) s')
785+ next (NS s) = case next0 s of
780786 Done -> Done
781− Skip s' -> Skip (N :*: s')
782− Yield x s' -> Yield x (N :*: s')
787+ Skip s' -> Skip (NS s')
788+ Yield x s' -> Yield x (NS s')
783789{-# INLINE [0] drop #-}
784790
785791-- | takeWhile, applied to a predicate @p@ and a stream, returns the
@@ -915,21 +921,25 @@ findIndicesI p (Stream next s0 _len) = loop_findIndex 0 s0
915921-------------------------------------------------------------------------------
916922-- * Zipping
917923
924+-- | Strict triple.
925+data Zip a b m = Z1 !a !b
926+ | Z2 !a !b !m
927+
918928-- | zipWith generalises 'zip' by zipping with the function given as
919929-- the first argument, instead of a tupling function.
920930zipWith :: (a -> a -> b) -> Stream a -> Stream a -> Stream b
921931zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) =
922− Stream next (T3 sa0 sb0 N) (smaller len1 len2)
932+ Stream next (Z1 sa0 sb0) (smaller len1 len2)
923933 where
924− next (T3 sa sb N) = case next0 sa of
925− Done -> Done
926− Skip sa' -> Skip (T3 sa' sb N)
927− Yield a sa' -> Skip (T3 sa' sb (J a))
928−
929− next (T3 sa' sb (J a)) = case next1 sb of
930− Done -> Done
931− Skip sb' -> Skip (T3 sa' sb' (J a))
932− Yield b sb' -> Yield (f a b) (T3 sa' sb' N)
934+ next (Z1 sa sb) = case next0 sa of
935+ Done -> Done
936+ Skip sa' -> Skip (Z1 sa' sb)
937+ Yield a sa' -> Skip (Z2 sa' sb a)
938+
939+ next (Z2 sa' sb a) = case next1 sb of
940+ Done -> Done
941+ Skip sb' -> Skip (Z2 sa' sb' a)
942+ Yield b sb' -> Yield (f a b) (Z1 sa' sb')
933943{-# INLINE [0] zipWith #-}
934944
935945-- | /O(n)/ The 'countCharI' function returns the number of times the