{-# LANGUAGE BangPatterns, ExistentialQuantification #-}
module Data.JSString.Internal.Fusion.Types
(
CC(..)
, M(..)
, M8
, PairS(..)
, RS(..)
, Step(..)
, Stream(..)
, Switch(..)
, empty
) where
import Data.Word (Word8)
data CC s = CC !s {-# UNPACK #-} !Char {-# UNPACK #-} !Char
data M a = N
| J !a
type M8 = M Word8
data RS s
= RS0 !s
| RS1 !s {-# UNPACK #-} !Word8
| RS2 !s {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
| RS3 !s {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
infixl 2 :*:
data PairS a b = !a :*: !b
data Switch = S1 | S2
data Step s a = Done
| Skip !s
| Yield !a !s
instance (Eq a) => Eq (Stream a) where
(==) = eq
instance (Ord a) => Ord (Stream a) where
compare = cmp
data Stream a =
forall s. Stream
(s -> Step s a)
!s
eq :: (Eq a) => Stream a -> Stream a -> Bool
eq (Stream next1 s1) (Stream next2 s2) = loop (next1 s1) (next2 s2)
where
loop Done Done = True
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 Done _ = False
loop _ Done = False
loop (Yield x1 s1') (Yield x2 s2') = x1 == x2 &&
loop (next1 s1') (next2 s2')
{-# INLINE [0] eq #-}
cmp :: (Ord a) => Stream a -> Stream a -> Ordering
cmp (Stream next1 s1) (Stream next2 s2) = loop (next1 s1) (next2 s2)
where
loop Done Done = EQ
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 Done _ = LT
loop _ Done = GT
loop (Yield x1 s1') (Yield x2 s2') =
case compare x1 x2 of
EQ -> loop (next1 s1') (next2 s2')
other -> other
{-# INLINE [0] cmp #-}
empty :: Stream a
empty = Stream next ()
where next _ = Done
{-# INLINE [0] empty #-}