{-# LANGUAGE CPP #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE LambdaCase #-}
module Unicode.Internal.Unfold
( Unfold(..)
, Step(..)
, toList
) where
#if MIN_VERSION_base(4,12,0)
data Unfold a b = forall s. Unfold
(s -> Step s b)
(a -> Step s b)
#else
data Unfold a b =
forall s. Unfold (s -> Step s b) (a -> Step s b)
#endif
data Step s a
= Yield !a !s
| Stop
instance Functor (Step s) where
{-# INLINE fmap #-}
fmap :: forall a b. (a -> b) -> Step s a -> Step s b
fmap a -> b
f (Yield a
x s
s) = b -> s -> Step s b
forall s a. a -> s -> Step s a
Yield (a -> b
f a
x) s
s
fmap a -> b
_ Step s a
Stop = Step s b
forall s a. Step s a
Stop
{-# INLINE toList #-}
toList :: Unfold a a -> a -> [a]
toList :: forall a. Unfold a a -> a -> [a]
toList (Unfold s -> Step s a
step a -> Step s a
inject) a
input =
case a -> Step s a
inject a
input of
Step s a
Stop -> [a
input]
Yield a
b s
s -> a
b a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Step s a -> [a]
go (s -> Step s a
step s
s)
where
go :: Step s a -> [a]
go = \case
Yield a
b s
s -> let !s' :: Step s a
s' = s -> Step s a
step s
s in a
b a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Step s a -> [a]
go Step s a
s'
Step s a
Stop -> []